New upstream version 5.3.1~repack
authorIOhannes m zmölnig <zmoelnig@umlautS.umlaeute.mur.at>
Wed, 11 Apr 2018 18:40:38 +0000 (20:40 +0200)
committerIOhannes m zmölnig <zmoelnig@umlautS.umlaeute.mur.at>
Wed, 11 Apr 2018 18:40:38 +0000 (20:40 +0200)
448 files changed:
ChangeList.txt
examples/Assets/DemoUtilities.h
examples/Audio/AudioAppDemo.h
examples/Audio/AudioLatencyDemo.h
examples/Audio/AudioPlaybackDemo.h
examples/Audio/AudioRecordingDemo.h
examples/Audio/AudioSettingsDemo.h
examples/Audio/AudioSynthesiserDemo.h
examples/Audio/MPEDemo.h
examples/Audio/MidiDemo.h
examples/Audio/PluckedStringsDemo.h
examples/Audio/SimpleFFTDemo.h
examples/BLOCKS/BlocksDrawingDemo.h
examples/BLOCKS/BlocksMonitorDemo.h
examples/BLOCKS/BlocksSynthDemo.h
examples/DSP/ConvolutionDemo.h
examples/DSP/FIRFilterDemo.h
examples/DSP/GainDemo.h
examples/DSP/IIRFilterDemo.h
examples/DSP/OscillatorDemo.h
examples/DSP/OverdriveDemo.h
examples/DSP/SIMDRegisterDemo.h
examples/DSP/StateVariableFilterDemo.h
examples/DSP/WaveShaperTanhDemo.h
examples/DemoRunner/Builds/Android/app/CMakeLists.txt
examples/DemoRunner/Builds/Android/app/build.gradle
examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml
examples/DemoRunner/Builds/Android/app/src/main/assets/DemoUtilities.h
examples/DemoRunner/Builds/Android/app/src/main/java/com/roli/juce/demorunner/DemoRunner.java
examples/DemoRunner/Builds/Android/build.gradle
examples/DemoRunner/Builds/Android/gradle/wrapper/gradle-wrapper.properties
examples/DemoRunner/Builds/LinuxMakefile/Makefile
examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj
examples/DemoRunner/Builds/MacOSX/Info-App.plist
examples/DemoRunner/Builds/VisualStudio2013/DemoRunner.sln
examples/DemoRunner/Builds/VisualStudio2013/DemoRunner_App.vcxproj
examples/DemoRunner/Builds/VisualStudio2013/DemoRunner_App.vcxproj.filters
examples/DemoRunner/Builds/VisualStudio2013/resources.rc
examples/DemoRunner/Builds/VisualStudio2015/DemoRunner.sln
examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj
examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters
examples/DemoRunner/Builds/VisualStudio2015/resources.rc
examples/DemoRunner/Builds/VisualStudio2017/DemoRunner.sln
examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj
examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters
examples/DemoRunner/Builds/VisualStudio2017/resources.rc
examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj
examples/DemoRunner/Builds/iOS/Info-App.plist
examples/DemoRunner/DemoRunner.jucer
examples/DemoRunner/JuceLibraryCode/AppConfig.h
examples/DemoRunner/JuceLibraryCode/JuceHeader.h
examples/DemoRunner/Source/Demos/DemoPIPs1.cpp
examples/DemoRunner/Source/Demos/JUCEDemos.cpp
examples/DemoRunner/Source/UI/DemoContentComponent.cpp
examples/DemoRunner/Source/UI/MainComponent.cpp
examples/DemoRunner/Source/UI/MainComponent.h
examples/GUI/AnimationAppDemo.h
examples/GUI/AnimationDemo.h
examples/GUI/BouncingBallWavetableDemo.h
examples/GUI/CameraDemo.h
examples/GUI/CodeEditorDemo.h
examples/GUI/ComponentDemo.h
examples/GUI/ComponentTransformsDemo.h
examples/GUI/DialogsDemo.h
examples/GUI/FlexBoxDemo.h
examples/GUI/FontsDemo.h
examples/GUI/GraphicsDemo.h
examples/GUI/GridDemo.h
examples/GUI/HelloWorldDemo.h
examples/GUI/ImagesDemo.h
examples/GUI/KeyMappingsDemo.h
examples/GUI/LookAndFeelDemo.h
examples/GUI/MDIDemo.h
examples/GUI/MenusDemo.h
examples/GUI/MultiTouchDemo.h
examples/GUI/OpenGLAppDemo.h
examples/GUI/OpenGLDemo.h
examples/GUI/OpenGLDemo2D.h
examples/GUI/PropertiesDemo.h
examples/GUI/VideoDemo.h
examples/GUI/WebBrowserDemo.h
examples/GUI/WidgetsDemo.h
examples/GUI/WindowsDemo.h
examples/Plugins/AUv3SynthPluginDemo.h
examples/Plugins/ArpeggiatorPluginDemo.h
examples/Plugins/AudioPluginDemo.h
examples/Plugins/DSPModulePluginDemo.h
examples/Plugins/GainPluginDemo.h
examples/Plugins/InterAppAudioEffectPluginDemo.h
examples/Plugins/MultiOutSynthPluginDemo.h
examples/Plugins/NoiseGatePluginDemo.h
examples/Plugins/SamplerPluginDemo.h
examples/Plugins/SurroundPluginDemo.h
examples/Utilities/AnalyticsCollectionDemo.h
examples/Utilities/Box2DDemo.h
examples/Utilities/ChildProcessDemo.h
examples/Utilities/CryptographyDemo.h
examples/Utilities/InAppPurchasesDemo.h
examples/Utilities/JavaScriptDemo.h
examples/Utilities/LiveConstantDemo.h
examples/Utilities/MultithreadingDemo.h
examples/Utilities/NetworkingDemo.h
examples/Utilities/OSCDemo.h
examples/Utilities/PushNotificationsDemo.h
examples/Utilities/SimpleFFTDemo.h [deleted file]
examples/Utilities/SystemInfoDemo.h
examples/Utilities/TimersAndEventsDemo.h
examples/Utilities/UnitTestsDemo.h
examples/Utilities/ValueTreesDemo.h
examples/Utilities/XMLandJSONDemo.h
extras/AudioPerformanceTest/AudioPerformanceTest.jucer
extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
extras/AudioPerformanceTest/Builds/Android/app/build.gradle
extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/juce/audioperformancetest/AudioPerformanceTest.java
extras/AudioPerformanceTest/Builds/Android/build.gradle
extras/AudioPerformanceTest/Builds/Android/gradle/wrapper/gradle-wrapper.properties
extras/AudioPerformanceTest/Builds/VisualStudio2015/AudioPerformanceTest_App.vcxproj
extras/AudioPerformanceTest/Builds/VisualStudio2015/AudioPerformanceTest_App.vcxproj.filters
extras/AudioPerformanceTest/JuceLibraryCode/AppConfig.h
extras/AudioPluginHost/AudioPluginHost.jucer
extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/app/build.gradle [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/app/src/debug/res/values/string.xml [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/app/src/main/AndroidManifest.xml [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/app/src/main/java/com/android/vending/billing/IInAppBillingService.java [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/app/src/main/java/com/roli/juce/pluginhost/AudioPluginHost.java [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/app/src/main/java/com/roli/juce/pluginhost/SharingContentProvider.java [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-hdpi/icon.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-ldpi/icon.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-mdpi/icon.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-xhdpi/icon.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/app/src/release/res/values/string.xml [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/build.gradle [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/gradle/wrapper/LICENSE-for-gradlewrapper.txt [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/gradle/wrapper/gradle-wrapper.jar [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/gradle/wrapper/gradle-wrapper.properties [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/gradlew [new file with mode: 0755]
extras/AudioPluginHost/Builds/Android/gradlew.bat [new file with mode: 0644]
extras/AudioPluginHost/Builds/Android/settings.gradle [new file with mode: 0644]
extras/AudioPluginHost/Builds/LinuxMakefile/Makefile
extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj
extras/AudioPluginHost/Builds/MacOSX/Icon.icns [new file with mode: 0644]
extras/AudioPluginHost/Builds/MacOSX/Info-App.plist
extras/AudioPluginHost/Builds/VisualStudio2013/AudioPluginHost_App.vcxproj
extras/AudioPluginHost/Builds/VisualStudio2013/AudioPluginHost_App.vcxproj.filters
extras/AudioPluginHost/Builds/VisualStudio2013/icon.ico [new file with mode: 0644]
extras/AudioPluginHost/Builds/VisualStudio2013/resources.rc
extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj
extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters
extras/AudioPluginHost/Builds/VisualStudio2015/icon.ico [new file with mode: 0644]
extras/AudioPluginHost/Builds/VisualStudio2015/resources.rc
extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj
extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters
extras/AudioPluginHost/Builds/VisualStudio2017/icon.ico [new file with mode: 0644]
extras/AudioPluginHost/Builds/VisualStudio2017/resources.rc
extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Contents.json [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-29.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-29@2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-29@3x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-72.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-72@2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-76.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-@3x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-AppStore-1024.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notification-20@2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notification-20@3x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notifications-20.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notifications-20@2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small-1.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small-50.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon@2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/Contents.json [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-landscape-1x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-landscape-2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-portrait-1x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-portrait-2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-iphone-2x.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-iphone-retina4.png [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/Icon.icns [new file with mode: 0644]
extras/AudioPluginHost/Builds/iOS/Info-App.plist [new file with mode: 0644]
extras/AudioPluginHost/JuceLibraryCode/AppConfig.h
extras/AudioPluginHost/JuceLibraryCode/BinaryData.cpp [new file with mode: 0644]
extras/AudioPluginHost/JuceLibraryCode/BinaryData.h [new file with mode: 0644]
extras/AudioPluginHost/JuceLibraryCode/JuceHeader.h
extras/AudioPluginHost/Source/FilterGraph.cpp [deleted file]
extras/AudioPluginHost/Source/FilterGraph.h [deleted file]
extras/AudioPluginHost/Source/FilterIOConfiguration.cpp [deleted file]
extras/AudioPluginHost/Source/FilterIOConfiguration.h [deleted file]
extras/AudioPluginHost/Source/Filters/FilterGraph.cpp [new file with mode: 0644]
extras/AudioPluginHost/Source/Filters/FilterGraph.h [new file with mode: 0644]
extras/AudioPluginHost/Source/Filters/FilterIOConfiguration.cpp [new file with mode: 0644]
extras/AudioPluginHost/Source/Filters/FilterIOConfiguration.h [new file with mode: 0644]
extras/AudioPluginHost/Source/Filters/InternalFilters.cpp [new file with mode: 0644]
extras/AudioPluginHost/Source/Filters/InternalFilters.h [new file with mode: 0644]
extras/AudioPluginHost/Source/GraphEditorPanel.cpp [deleted file]
extras/AudioPluginHost/Source/GraphEditorPanel.h [deleted file]
extras/AudioPluginHost/Source/HostStartup.cpp
extras/AudioPluginHost/Source/InternalFilters.cpp [deleted file]
extras/AudioPluginHost/Source/InternalFilters.h [deleted file]
extras/AudioPluginHost/Source/JUCEAppIcon.png [new file with mode: 0644]
extras/AudioPluginHost/Source/MainHostWindow.cpp [deleted file]
extras/AudioPluginHost/Source/MainHostWindow.h [deleted file]
extras/AudioPluginHost/Source/PluginWindow.h [deleted file]
extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp [new file with mode: 0644]
extras/AudioPluginHost/Source/UI/GraphEditorPanel.h [new file with mode: 0644]
extras/AudioPluginHost/Source/UI/MainHostWindow.cpp [new file with mode: 0644]
extras/AudioPluginHost/Source/UI/MainHostWindow.h [new file with mode: 0644]
extras/AudioPluginHost/Source/UI/PluginWindow.h [new file with mode: 0644]
extras/BLOCKS/doxygen/Doxyfile [deleted file]
extras/BLOCKS/doxygen/DoxygenLayout.xml [deleted file]
extras/BLOCKS/doxygen/Makefile [deleted file]
extras/BLOCKS/doxygen/footer.html [deleted file]
extras/BLOCKS/doxygen/header.html [deleted file]
extras/BLOCKS/doxygen/images/BlocksDrawing_canvas.JPG [deleted file]
extras/BLOCKS/doxygen/images/BlocksDrawing_palette.JPG [deleted file]
extras/BLOCKS/doxygen/images/BlocksMonitor.png [deleted file]
extras/BLOCKS/doxygen/images/BlocksSynth_grid.JPG [deleted file]
extras/BLOCKS/doxygen/images/BlocksSynth_waveshape.gif [deleted file]
extras/BLOCKS/doxygen/pages/juce_connecting_blocks.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_controlling_control_buttons.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_controlling_led_grids.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_controlling_led_strips.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_discovering_blocks.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_downloading_the_sdk.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_example_applications.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_example_blocks_drawing.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_example_blocks_monitor.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_example_blocks_synth.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_getting_control_button_events.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_getting_touch_events.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_main.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_the_littlefoot_language.dox [deleted file]
extras/BLOCKS/doxygen/pages/juce_the_standalone_blocks_sdk.dox [deleted file]
extras/BLOCKS/doxygen/stylesheet.css [deleted file]
extras/BLOCKS/standalone_sdk/README.md
extras/BLOCKS/standalone_sdk/SDK/BlocksHeader.h
extras/BLOCKS/standalone_sdk/examples/BlockFinder/BlockFinder.cpp
extras/BLOCKS/standalone_sdk/examples/BlockFinder/BlockFinder.h
extras/BLOCKS/standalone_sdk/examples/BlockFinder/Linux/main.cpp
extras/BLOCKS/standalone_sdk/examples/BlockFinder/MacOS/Makefile
extras/BLOCKS/standalone_sdk/examples/BlockFinder/MacOS/main.mm
extras/BLOCKS/standalone_sdk/examples/BlockFinder/Windows/main.cpp
extras/BinaryBuilder/BinaryBuilder.jucer
extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
extras/NetworkGraphicsDemo/Builds/Android/app/build.gradle
extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/juce/networkgraphicsdemo/JUCENetworkGraphicsDemo.java
extras/NetworkGraphicsDemo/Builds/Android/build.gradle
extras/NetworkGraphicsDemo/Builds/Android/gradle/wrapper/gradle-wrapper.properties
extras/NetworkGraphicsDemo/Builds/VisualStudio2013/NetworkGraphicsDemo_App.vcxproj
extras/NetworkGraphicsDemo/Builds/VisualStudio2013/NetworkGraphicsDemo_App.vcxproj.filters
extras/NetworkGraphicsDemo/Builds/VisualStudio2017/NetworkGraphicsDemo_App.vcxproj
extras/NetworkGraphicsDemo/Builds/VisualStudio2017/NetworkGraphicsDemo_App.vcxproj.filters
extras/NetworkGraphicsDemo/JuceLibraryCode/AppConfig.h
extras/NetworkGraphicsDemo/JuceLibraryCode/BinaryData.cpp
extras/NetworkGraphicsDemo/JuceLibraryCode/BinaryData.h
extras/NetworkGraphicsDemo/NetworkGraphicsDemo.jucer
extras/Projucer/Builds/LinuxMakefile/Makefile
extras/Projucer/Builds/MacOSX/Info-App.plist
extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj
extras/Projucer/Builds/VisualStudio2013/Projucer_App.vcxproj
extras/Projucer/Builds/VisualStudio2013/Projucer_App.vcxproj.filters
extras/Projucer/Builds/VisualStudio2013/resources.rc
extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj
extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj.filters
extras/Projucer/Builds/VisualStudio2015/resources.rc
extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj
extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters
extras/Projucer/Builds/VisualStudio2017/resources.rc
extras/Projucer/JuceLibraryCode/BinaryData.cpp
extras/Projucer/JuceLibraryCode/BinaryData.h
extras/Projucer/JuceLibraryCode/JuceHeader.h
extras/Projucer/Projucer.jucer
extras/Projucer/Source/Application/Windows/jucer_ApplicationUsageDataWindowComponent.h
extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h [new file with mode: 0644]
extras/Projucer/Source/Application/jucer_Application.cpp
extras/Projucer/Source/Application/jucer_Application.h
extras/Projucer/Source/Application/jucer_CommandIDs.h
extras/Projucer/Source/Application/jucer_CommandLine.cpp
extras/Projucer/Source/Application/jucer_Main.cpp
extras/Projucer/Source/Application/jucer_MainWindow.cpp
extras/Projucer/Source/Application/jucer_MainWindow.h
extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp
extras/Projucer/Source/Application/jucer_ProjucerAnalytics.h
extras/Projucer/Source/BinaryData/Templates/jucer_PIPAudioProcessorTemplate.h [new file with mode: 0644]
extras/Projucer/Source/BinaryData/Templates/jucer_PIPMain.cpp
extras/Projucer/Source/BinaryData/Templates/jucer_PIPTemplate.h [new file with mode: 0644]
extras/Projucer/Source/ComponentEditor/Properties/jucer_FontPropertyComponent.h
extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.cpp
extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.h
extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineDLL.h
extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineSettings.h [new file with mode: 0644]
extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h
extras/Projucer/Source/Project/UI/Sidebar/jucer_ModuleTreeItems.h
extras/Projucer/Source/Project/UI/jucer_ContentViewComponents.h
extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp
extras/Projucer/Source/Project/jucer_Module.cpp
extras/Projucer/Source/Project/jucer_Module.h
extras/Projucer/Source/Project/jucer_Project.cpp
extras/Projucer/Source/Project/jucer_Project.h
extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h
extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h
extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CodeBlocks.h
extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h
extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h
extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h
extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp
extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h
extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.cpp
extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h
extras/Projucer/Source/ProjectSaving/jucer_ResourceFile.cpp
extras/Projucer/Source/Settings/jucer_StoredSettings.cpp
extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.cpp
extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.h
extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h
extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp
extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.h
extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h
extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.cpp
extras/Projucer/Source/Wizards/jucer_NewProjectWizard.h
extras/Projucer/Source/Wizards/jucer_TemplateThumbnailsComponent.h
extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj
extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj
extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters
extras/UnitTestRunner/JuceLibraryCode/AppConfig.h
extras/UnitTestRunner/UnitTestRunner.jucer
extras/WindowsDLL/Builds/VisualStudio2017/WindowsDLL_StaticLibrary.vcxproj
extras/WindowsDLL/Builds/VisualStudio2017/WindowsDLL_StaticLibrary.vcxproj.filters
extras/WindowsDLL/JuceLibraryCode/AppConfig.h
extras/WindowsDLL/WindowsDLL.jucer
modules/juce_analytics/juce_analytics.h
modules/juce_audio_basics/juce_audio_basics.h
modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp
modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h
modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp
modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp
modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h
modules/juce_audio_devices/juce_audio_devices.cpp
modules/juce_audio_devices/juce_audio_devices.h
modules/juce_audio_devices/native/juce_linux_ALSA.cpp
modules/juce_audio_devices/native/juce_linux_Bela.cpp [new file with mode: 0644]
modules/juce_audio_devices/native/juce_win32_Midi.cpp
modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp
modules/juce_audio_formats/juce_audio_formats.h
modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp
modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp
modules/juce_audio_plugin_client/juce_audio_plugin_client.h
modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm
modules/juce_audio_plugin_client/utility/juce_PluginHostType.h
modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm
modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp [new file with mode: 0644]
modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
modules/juce_audio_processors/juce_audio_processors.cpp
modules/juce_audio_processors/juce_audio_processors.h
modules/juce_audio_processors/processors/juce_AudioPluginInstance.h
modules/juce_audio_processors/processors/juce_AudioProcessor.cpp
modules/juce_audio_processors/processors/juce_AudioProcessor.h
modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h
modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp
modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h
modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp
modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h
modules/juce_audio_utils/juce_audio_utils.h
modules/juce_blocks_basics/juce_blocks_basics.h
modules/juce_box2d/juce_box2d.h
modules/juce_core/containers/juce_ElementComparator.h
modules/juce_core/containers/juce_SparseSet.h
modules/juce_core/files/juce_File.cpp
modules/juce_core/files/juce_File.h
modules/juce_core/juce_core.h
modules/juce_core/maths/juce_MathsFunctions.h
modules/juce_core/maths/juce_NormalisableRange.h
modules/juce_core/memory/juce_ByteOrder.h
modules/juce_core/native/java/JuceAppActivity.java
modules/juce_core/native/juce_BasicNativeHeaders.h
modules/juce_core/native/juce_linux_CommonFile.cpp
modules/juce_core/native/juce_mac_Files.mm
modules/juce_core/native/juce_mac_Network.mm
modules/juce_core/native/juce_posix_SharedCode.h
modules/juce_core/native/juce_win32_Files.cpp
modules/juce_core/streams/juce_URLInputSource.h
modules/juce_core/system/juce_StandardHeader.h
modules/juce_core/threads/juce_ThreadPool.cpp
modules/juce_core/xml/juce_XmlElement.cpp
modules/juce_core/xml/juce_XmlElement.h
modules/juce_core/zip/juce_ZipFile.cpp
modules/juce_core/zip/juce_ZipFile.h
modules/juce_cryptography/juce_cryptography.h
modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp
modules/juce_data_structures/juce_data_structures.h
modules/juce_data_structures/undomanager/juce_UndoManager.cpp
modules/juce_data_structures/undomanager/juce_UndoManager.h
modules/juce_data_structures/values/juce_ValueWithDefault.h
modules/juce_dsp/frequency/juce_FFT.cpp
modules/juce_dsp/frequency/juce_FFT.h
modules/juce_dsp/juce_dsp.h
modules/juce_dsp/maths/juce_Matrix.cpp
modules/juce_dsp/processors/juce_Oversampling.cpp
modules/juce_events/juce_events.h
modules/juce_graphics/geometry/juce_Rectangle.h
modules/juce_graphics/juce_graphics.h
modules/juce_graphics/native/juce_android_Fonts.cpp
modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm
modules/juce_graphics/native/juce_mac_Fonts.mm
modules/juce_gui_basics/components/juce_Component.cpp
modules/juce_gui_basics/components/juce_Component.h
modules/juce_gui_basics/filebrowser/juce_ContentSharer.cpp
modules/juce_gui_basics/juce_gui_basics.cpp
modules/juce_gui_basics/juce_gui_basics.h
modules/juce_gui_basics/layout/juce_Grid.cpp
modules/juce_gui_basics/layout/juce_Viewport.cpp
modules/juce_gui_basics/layout/juce_Viewport.h
modules/juce_gui_basics/menus/juce_PopupMenu.cpp
modules/juce_gui_basics/mouse/juce_MouseEvent.h
modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp
modules/juce_gui_basics/mouse/juce_MouseInputSource.h
modules/juce_gui_basics/mouse/juce_MouseListener.cpp
modules/juce_gui_basics/mouse/juce_MouseListener.h
modules/juce_gui_basics/native/juce_mac_MainMenu.mm
modules/juce_gui_basics/native/juce_mac_Windowing.mm
modules/juce_gui_basics/native/juce_win32_Windowing.cpp
modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp
modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h
modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp [new file with mode: 0644]
modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h [new file with mode: 0644]
modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp
modules/juce_gui_basics/properties/juce_TextPropertyComponent.h
modules/juce_gui_basics/widgets/juce_TextEditor.cpp
modules/juce_gui_basics/widgets/juce_TextEditor.h
modules/juce_gui_basics/windows/juce_AlertWindow.cpp
modules/juce_gui_extra/juce_gui_extra.h
modules/juce_opengl/juce_opengl.h
modules/juce_osc/juce_osc.h
modules/juce_product_unlocking/juce_product_unlocking.h
modules/juce_video/juce_video.h

index 9d1f7f391b254f793ff918c8c581e415cc608bc5..38978ff288d07e48648bb39292b6d0eee680038e 100644 (file)
@@ -3,12 +3,31 @@
 \r
 This file just lists the more notable headline features. For more detailed info\r
 about minor changes and bugfixes, please see the git log!\r
+
+Version 5.3.1\r
+  - Add Android and iOS support to AudioPluginHost\r
+  - Added support for Bela in the form of an AudioIODeviceType\r
+  - Add bypass support to both hosting and plug-in client code\r
+  - Added an isBoolean flag to APVTS parameters\r
+  - Re-worked plug-in wrappers to all use new parameter system via LegacyAudioParameter wrapper class\r
+  - Fixed an issue where opening the same midi device twice would cause a crash on Windows\r
+  - Deprecated MouseInputSource::hasMouseMovedSignificantlySincePressed() and replaced with more descriptive methods\r
+  - Added support for relative or special path symbolic links when compressing/uncompressing zip archives and creating/reading files\r
+  - Ensured that File::replaceInternal does not fail with ACL errors on Windows\r
+  - Merged-in some Ogg-Vorbis security fixes\r
+  - Fixed a bug which would prevent a SystemTrayIconComponent from creating a native popup window on macOS\r
+  - Various Android and iOS fixes\r
+  - Added a "PIP Creator" utility tool to the Projucer\r
+  - Added options for setting plugin categories and characteristics with MultiChoicePropertyComponent in the Projucer\r
+  - Fixed a Projucer bug where the OSX base SDK version was not being set\r
+  - Added a command-line option to use LF as linefeeds rather than CRLF in the Projucer cleanup tools\r
+  - Multiple documentation updates
 \r
 Version 5.3.0\r
   - Added support for Android OBOE (developer preview)\r
   - Updated JUCE's MPE classes to comply with the new MMA-adopted specification\r
   - Multiple documentation updates\r
-  - Restructed the examples and extras directories and updated all JUCE examples\r
+  - Restructured the examples and extras directories and updated all JUCE examples\r
   - Multiple hosted parameter improvements\r
   - Overhauled the GenericAudioProcessorEditor\r
   - Added support for a subset of the Cockos VST extensions\r
index fa995e374e622e28344289a1637ed7e822ddf26b..92108d8490bb9896268ed7c338dbbeb0d29f31d9 100644 (file)
@@ -58,7 +58,11 @@ inline File getExamplesDirectory() noexcept
 \r
     return mo.toString();\r
    #else\r
-    auto currentFile = File::getSpecialLocation (File::SpecialLocationType::currentExecutableFile);\r
+    auto currentFile = File::getSpecialLocation (File::SpecialLocationType::currentApplicationFile);\r
+    auto exampleDir = currentFile.getParentDirectory().getChildFile ("examples");\r
+\r
+    if (exampleDir.exists())\r
+        return exampleDir;\r
 \r
     int numTries = 0; // keep track of the number of parent directories so we don't go on endlessly\r
 \r
index 8ed8d0d1ef23f317049bc21f665dbabef3ba8e76..d1db7ab1a151cfe477dd6ff6e9a8815296241826 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             AudioAppDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Simple audio application.\r
 \r
index 458f4b9eac56b1754e24dc7461bb577bc8817a74..7920d453dedf19f75984536dd51ae8aecdb95c7f 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             AudioLatencyDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Tests the audio latency of a device.\r
 \r
index b87be3b6c575a52e1c7b2afc9d4bcc2299db4f1d..b0f942f9c7b83661a816d5207ac9fec5b5cacbcb 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             AudioPlaybackDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Plays an audio file.\r
 \r
index da0ec12a2a1fa1c283acbd965268985c820a26e7..932832569d55d50a36df4a909f1be04137806896 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             AudioRecordingDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Records audio to a file.\r
 \r
index 9ac09ec38350204495a499a5d8b4264c3e480362..08ff2b9df319948a8e3f50dc4230a5342045e374 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             AudioSettingsDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Displays information about audio devices.\r
 \r
index 1c5e83cb0400fee79432244465bb5194e1002486..cfed6dfe5a1e997446f45d96f93862ebb3738c56 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             AudioSynthesiserDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Simple synthesiser application.\r
 \r
index 12f74188e12f305456fc774eb27156464d0131af..e1e2c5c4ec0757f62215102701c0b5fcf71acf52 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             MPEDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Simple MPE synthesiser application.\r
 \r
index f0e77b06a4017016212c24091a72066d394af936..6b6e33f2c45add44dccde4cbed4f3ba6371b5cff 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             MidiDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Handles incoming and outcoming midi messages.\r
 \r
@@ -101,7 +101,7 @@ public:
             pairButton.setEnabled (false);\r
 \r
         addAndMakeVisible (pairButton);\r
-        pairButton.onClick = [this]\r
+        pairButton.onClick = []\r
         {\r
             RuntimePermissions::request (RuntimePermissions::bluetoothMidi,\r
                                          [] (bool wasGranted)\r
@@ -285,7 +285,7 @@ private:
         }\r
 \r
         //==============================================================================\r
-        void paintListBoxItem (int rowNumber, Graphics &g,\r
+        void paintListBoxItem (int rowNumber, Graphicsg,\r
                                int width, int height, bool rowIsSelected) override\r
         {\r
             auto textColour = getLookAndFeel().findColour (ListBox::textColourId);\r
@@ -356,7 +356,7 @@ private:
     };\r
 \r
     //==============================================================================\r
-    void handleIncomingMidiMessage (MidiInput* /*source*/, const MidiMessage &message) override\r
+    void handleIncomingMidiMessage (MidiInput* /*source*/, const MidiMessagemessage) override\r
     {\r
         // This is called on the MIDI thread\r
 \r
index cbdc63cddcf123c6e6300b836dcc0c92a541bc7c..cf3b02b967520a986b7f51f90d81d97d03862cfb 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             PluckedStringsDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Simulation of a plucked string sound.\r
 \r
@@ -109,7 +109,7 @@ public:
         // cycle through the delay line and apply a simple averaging filter\r
         for (auto i = 0; i < numSamples; ++i)\r
         {\r
-            auto nextPos = (int) ((pos + 1) % delayLine.size());\r
+            auto nextPos = (pos + 1) % delayLine.size();\r
 \r
             delayLine[nextPos] = (float) (decay * 0.5 * (delayLine[nextPos] + delayLine[pos]));\r
             outBuffer[i] += delayLine[pos];\r
@@ -151,7 +151,7 @@ private:
                         excitationSample.end(),\r
                         delayLine.begin(),\r
                         [this] (double sample) { return static_cast<float> (amplitude * sample); } );\r
-    };\r
+    }\r
 \r
     //==============================================================================\r
     const double decay = 0.998;\r
@@ -160,7 +160,7 @@ private:
     Atomic<int> doPluckForNextBuffer;\r
 \r
     std::vector<float> excitationSample, delayLine;\r
-    int pos = 0;\r
+    size_t pos = 0;\r
 \r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StringSynthesiser)\r
 };\r
@@ -294,7 +294,7 @@ public:
             {\r
                 memcpy (channelData,\r
                         bufferToFill.buffer->getReadPointer (0),\r
-                        bufferToFill.numSamples * sizeof (float));\r
+                        ((size_t) bufferToFill.numSamples) * sizeof (float));\r
             }\r
         }\r
     }\r
index 6710efba7556b20ca051962388df0d91e6eb2f2c..2f99a29c1a4019c5760b0b099887dd473b7c3c2f 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             SimpleFFTDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Simple FFT application.\r
 \r
@@ -52,10 +52,10 @@ class SimpleFFTDemo   : public AudioAppComponent,
                         private Timer\r
 {\r
 public:\r
-    SimpleFFTDemo()\r
-       #ifdef JUCE_DEMO_RUNNER\r
-        : AudioAppComponent (getSharedAudioDeviceManager (1, 0)),\r
-       #endif\r
+    SimpleFFTDemo() :\r
+         #ifdef JUCE_DEMO_RUNNER\r
+          AudioAppComponent (getSharedAudioDeviceManager (1, 0)),\r
+         #endif\r
           forwardFFT (fftOrder),\r
           spectrogramImage (Image::RGB, 512, 512, true)\r
     {\r
index aed22ce5b87c22a4dd21323f33ff8ba1da2a9826..a2b241785e8c1d5bf54ea011d38b6a29872a80ae 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             BlocksDrawingDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Blocks application to draw shapes.\r
 \r
@@ -531,7 +531,7 @@ private:
                 for (uint32 y = 0; y < 15; ++ y)\r
                 {\r
                     canvasProgram->setLED (x, y, Colours::black);\r
-                    lightpadComponent.setLEDColour (x, y, Colours::black);\r
+                    lightpadComponent.setLEDColour ((int) x, (int) y, Colours::black);\r
                 }\r
             }\r
 \r
@@ -554,7 +554,7 @@ private:
                 if (index >= 0)\r
                 {\r
                     canvasProgram->setLED (x0, y0, Colours::black);\r
-                    lightpadComponent.setLEDColour (x0, y0, Colours::black);\r
+                    lightpadComponent.setLEDColour ((int) x0, (int) y0, Colours::black);\r
                     activeLeds.remove (index);\r
                 }\r
 \r
@@ -574,7 +574,7 @@ private:
                 activeLeds.add (led);\r
                 canvasProgram->setLED (led.x, led.y, led.colour.withBrightness (led.brightness));\r
 \r
-                lightpadComponent.setLEDColour (led.x, led.y, led.colour.withBrightness (led.brightness));\r
+                lightpadComponent.setLEDColour ((int) led.x, (int) led.y, led.colour.withBrightness (led.brightness));\r
 \r
                 return;\r
             }\r
@@ -594,7 +594,7 @@ private:
             if (canvasProgram != nullptr)\r
                 canvasProgram->setLED (currentLed.x, currentLed.y, currentLed.colour.withBrightness (currentLed.brightness));\r
 \r
-            lightpadComponent.setLEDColour (currentLed.x, currentLed.y, currentLed.colour.withBrightness (currentLed.brightness));\r
+            lightpadComponent.setLEDColour ((int) currentLed.x, (int) currentLed.y, currentLed.colour.withBrightness (currentLed.brightness));\r
 \r
             activeLeds.set (index, currentLed);\r
         }\r
@@ -609,7 +609,7 @@ private:
             for (auto led : activeLeds)\r
             {\r
                 canvasProgram->setLED (led.x, led.y, led.colour.withBrightness (led.brightness));\r
-                lightpadComponent.setLEDColour (led.x, led.y, led.colour.withBrightness (led.brightness));\r
+                lightpadComponent.setLEDColour ((int) led.x, (int) led.y, led.colour.withBrightness (led.brightness));\r
             }\r
         }\r
     }\r
@@ -648,6 +648,7 @@ private:
             return xPos == x && yPos == y;\r
         }\r
     };\r
+\r
     Array<ActiveLED> activeLeds;\r
 \r
     int getLEDAt (uint32 x, uint32 y) const\r
@@ -665,6 +666,7 @@ private:
         colourPalette = 0,\r
         canvas\r
     };\r
+\r
     DisplayMode currentMode = colourPalette;\r
 \r
     //==============================================================================\r
index e5bd9ffa5210b658c5060d596ba5aef415237772..9c064ffac82c19575d1065d7130303cbf024c007 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             BlocksMonitorDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Application to monitor Blocks devices.\r
 \r
@@ -136,15 +136,15 @@ public:
 \r
         static Array<ControlButton::ButtonFunction> map[] =\r
         {\r
-            { CB::mode,     CB::button0 },\r
-            { CB::volume,   CB::button1 },\r
-            { CB::scale,    CB::button2,    CB::click },\r
-            { CB::chord,    CB::button3,    CB::snap },\r
-            { CB::arp,      CB::button4,    CB::back },\r
-            { CB::sustain,  CB::button5,    CB::playOrPause },\r
-            { CB::octave,   CB::button6,    CB::record },\r
-            { CB::love,     CB::button7,    CB::learn },\r
-            { CB::up },\r
+            { CB::mode,     CB::button0,  CB::velocitySensitivity },\r
+            { CB::volume,   CB::button1,  CB::glideSensitivity    },\r
+            { CB::scale,    CB::button2,  CB::slideSensitivity,  CB::click       },\r
+            { CB::chord,    CB::button3,  CB::pressSensitivity,  CB::snap        },\r
+            { CB::arp,      CB::button4,  CB::liftSensitivity,   CB::back        },\r
+            { CB::sustain,  CB::button5,  CB::fixedVelocity,     CB::playOrPause },\r
+            { CB::octave,   CB::button6,  CB::glideLock,         CB::record      },\r
+            { CB::love,     CB::button7,  CB::pianoMode,         CB::learn       },\r
+            { CB::up   },\r
             { CB::down }\r
         };\r
 \r
@@ -748,7 +748,8 @@ private:
         if (type == Block::lightPadBlock)\r
             return new LightpadComponent (newBlock);\r
 \r
-        if (type == Block::loopBlock || type == Block::liveBlock)\r
+        if (type == Block::loopBlock || type == Block::liveBlock\r
+            || type == Block::touchBlock || type == Block::developerControlBlock)\r
             return new ControlBlockComponent (newBlock);\r
 \r
         // Should only be connecting a Lightpad or Control Block!\r
index 3782f4c3819a2a1a6dda6be5b3557e7871ce2b9f..b2ab1e1c6b63f96d967ad3f5d88246ccf7043f94 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             BlocksSynthDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Blocks synthesiser application.\r
 \r
@@ -160,7 +160,7 @@ struct SineSound : public SynthesiserSound
 */\r
 struct SineVoice : public OscillatorBase\r
 {\r
-    SineVoice() {};\r
+    SineVoice() {}\r
 \r
     bool canPlaySound (SynthesiserSound* sound) override { return dynamic_cast<SineSound*> (sound) != nullptr; }\r
 \r
@@ -191,7 +191,7 @@ struct SquareSound : public SynthesiserSound
 */\r
 struct SquareVoice : public OscillatorBase\r
 {\r
-    SquareVoice() {};\r
+    SquareVoice() {}\r
 \r
     bool canPlaySound (SynthesiserSound* sound) override { return dynamic_cast<SquareSound*> (sound) != nullptr; }\r
 \r
@@ -601,7 +601,7 @@ public:
        #endif\r
 \r
         setSize (600, 400);\r
-    };\r
+    }\r
 \r
     ~BlocksSynthDemo()\r
     {\r
@@ -751,7 +751,7 @@ private:
     void clearOldTouchTimes (const Time now)\r
     {\r
         for (auto i = touchMessageTimesInLastSecond.size(); --i >= 0;)\r
-            if (touchMessageTimesInLastSecond.getReference(i) < now - juce::RelativeTime::seconds (0.33))\r
+            if (touchMessageTimesInLastSecond.getReference(i) < now - RelativeTime::seconds (0.33))\r
                 touchMessageTimesInLastSecond.remove (i);\r
     }\r
 \r
@@ -835,7 +835,7 @@ private:
     PhysicalTopologySource topologySource;\r
     Block::Ptr activeBlock;\r
 \r
-    Array<juce::Time> touchMessageTimesInLastSecond;\r
+    Array<Time> touchMessageTimesInLastSecond;\r
 \r
     int waveshapeMode = 0;\r
 \r
index 3c67a52db2dcd89558ce6e7a10a46f7de13b7312..1391f4523171cd60d17febf32b2c52916156b56a 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             ConvolutionDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Convolution demo using the DSP module.\r
 \r
index a83766d917fde98abb03b7d2e4638a6865486578..bcb9ce55109396ba5eb71676ccdf23564de0cf1f 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             FIRFilterDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      FIR filter demo using the DSP module.\r
 \r
index e38bbcbe828ca053b0e1d44fe1af13f8d3b7f521..72ee5eb3002f340c5d91c36289c85dcd62371085 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             GainDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Gain demo using the DSP module.\r
 \r
index f1a8e40e3f3b777a7f5408aa0355e2ba0aac4f68..fe885fe3f28d4e2bb052f17c78392dba35f233d5 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             IIRFilterDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      IIR filter demo using the DSP module.\r
 \r
index ff5a8e8903cdc07d9a370e6cc5aac9928350dd52..28945a3d04e587f4e4ba6ab3e1d44a0d4d3fcffb 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             OscillatorDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Oscillator demo using the DSP module.\r
 \r
index 0ceb132ff4326c86a1bc837d36f3b7220ab64d43..8b929c5232f0126b31da7e7a61d7ae5c2b2d5270 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             OverdriveDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Overdrive demo using the DSP module.\r
 \r
index 3e9ef5f8924bb67b31903de97f3ad2822c2a6247..d17ba27edfef25c74e0668429b1b38d4d5bd6ecd 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             SIMDRegisterDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      SIMD register demo using the DSP module.\r
 \r
index 2daae52d6c0279f0772eef9ec80c76bc2a2cc875..ac4d98f66d9f64a10c62fd6646dc6915b58e25c4 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             StateVariableFilterDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      State variable filter demo using the DSP module.\r
 \r
index 6a5846de5c94abadce86764db63c190d1429b3a9..2da75a7af59155caf152c3ded0d6865e966706c2 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             WaveShaperTanhDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Wave shaper tanh demo using the DSP module.\r
 \r
index 5e5edd34bdc2894b881282c429c14ed02a188096..e9de472a27f65db0a49a1e32c6cbeac64d044343 100644 (file)
@@ -8,7 +8,7 @@ SET(BINARY_NAME "juce_jni")
 add_library("cpufeatures" STATIC "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c")\r
 set_source_files_properties("${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c" PROPERTIES COMPILE_FLAGS "-Wno-sign-conversion -Wno-gnu-statement-expression")\r
 \r
-add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_ANDROID_ACTIVITY_CLASSNAME=com_roli_juce_demorunner_DemoRunner" "-DJUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/roli/juce/demorunner/DemoRunner\"" "-DJUCE_ANDROID_SHARING_CONTENT_PROVIDER_CLASSNAME=com_roli_juce_demorunner_SharingContentProvider" "-DJUCE_ANDROID_SHARING_CONTENT_PROVIDER_CLASSPATH=\"com/roli/juce/demorunner/SharingContentProvider\"" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=5.2.1" "-DJUCE_APP_VERSION_HEX=0x50201")\r
+add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_ANDROID_ACTIVITY_CLASSNAME=com_roli_juce_demorunner_DemoRunner" "-DJUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/roli/juce/demorunner/DemoRunner\"" "-DJUCE_ANDROID_SHARING_CONTENT_PROVIDER_CLASSNAME=com_roli_juce_demorunner_SharingContentProvider" "-DJUCE_ANDROID_SHARING_CONTENT_PROVIDER_CLASSPATH=\"com/roli/juce/demorunner/SharingContentProvider\"" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=5.3.1" "-DJUCE_APP_VERSION_HEX=0x50301")\r
 \r
 include_directories( AFTER\r
     "../../../JuceLibraryCode"\r
@@ -141,6 +141,7 @@ add_library( ${BINARY_NAME}
     "../../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp"\r
     "../../../../../modules/juce_audio_devices/native/juce_ios_Audio.h"\r
     "../../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_linux_Bela.cpp"\r
     "../../../../../modules/juce_audio_devices/native/juce_linux_JackAudio.cpp"\r
     "../../../../../modules/juce_audio_devices/native/juce_linux_Midi.cpp"\r
     "../../../../../modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp"\r
@@ -323,6 +324,7 @@ add_library( ${BINARY_NAME}
     "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_VST3Common.h"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_VST3Headers.h"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp"\r
@@ -1275,6 +1277,8 @@ add_library( ${BINARY_NAME}
     "../../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"\r
     "../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp"\r
     "../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h"\r
     "../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp"\r
     "../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.h"\r
     "../../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp"\r
@@ -1599,6 +1603,7 @@ set_source_files_properties("../../../../../modules/juce_audio_devices/native/ju
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_ios_Audio.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_Bela.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_JackAudio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_Midi.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
@@ -1781,6 +1786,7 @@ set_source_files_properties("../../../../../modules/juce_audio_processors/format
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3Common.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3Headers.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
@@ -2733,6 +2739,8 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/properties/j
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
index fc308ba0086ab0d313e64dcbb7a6ef33a296c117..1bbe7b6c87ee3ac66f95487b5e1cc66f01a1069c 100644 (file)
@@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
 \r
 android {\r
     compileSdkVersion 23\r
-    buildToolsVersion "27.0.0"\r
+    buildToolsVersion "27.0.3"\r
     externalNativeBuild {\r
         cmake {\r
             path "CMakeLists.txt"\r
index 8c9726f37251f1aa5ce37fb456cc7e6908b8ee71..b1d2d7dba6d76ffa47607dce05a1be4350f49ec2 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="5.2.1"
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="5.3.1"
           package="com.roli.juce.demorunner">
   <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"/>
   <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23"/>
index fa995e374e622e28344289a1637ed7e822ddf26b..92108d8490bb9896268ed7c338dbbeb0d29f31d9 100644 (file)
@@ -58,7 +58,11 @@ inline File getExamplesDirectory() noexcept
 \r
     return mo.toString();\r
    #else\r
-    auto currentFile = File::getSpecialLocation (File::SpecialLocationType::currentExecutableFile);\r
+    auto currentFile = File::getSpecialLocation (File::SpecialLocationType::currentApplicationFile);\r
+    auto exampleDir = currentFile.getParentDirectory().getChildFile ("examples");\r
+\r
+    if (exampleDir.exists())\r
+        return exampleDir;\r
 \r
     int numTries = 0; // keep track of the number of parent directories so we don't go on endlessly\r
 \r
index d406d7133dfbf174b9833b0474022e3ead010672..af0505a40d4cb9fcd83b5614971761f63bf31621 100644 (file)
@@ -1238,7 +1238,10 @@ public class DemoRunner   extends Activity
 \r
         // Ensure that navigation/status bar visibility is correctly restored.\r
         for (int i = 0; i < viewHolder.getChildCount(); ++i)\r
-            ((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();\r
+        {\r
+            if (viewHolder.getChildAt (i) instanceof ComponentPeerView)\r
+                ((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();\r
+        }\r
     }\r
 \r
     @Override\r
@@ -1820,19 +1823,37 @@ public class DemoRunner   extends Activity
 \r
             private class TreeObserver implements ViewTreeObserver.OnGlobalLayoutListener\r
             {\r
+                TreeObserver()\r
+                {\r
+                    keyboardShown = false;\r
+                }\r
+\r
                 @Override\r
                 public void onGlobalLayout()\r
                 {\r
                     Rect r = new Rect();\r
 \r
-                    view.getWindowVisibleDisplayFrame(r);\r
+                    ViewGroup parentView = (ViewGroup) getParent();\r
+\r
+                    if (parentView == null)\r
+                        return;\r
 \r
-                    int diff = view.getHeight() - (r.bottom - r.top);\r
+                    parentView.getWindowVisibleDisplayFrame (r);\r
+\r
+                    int diff = parentView.getHeight() - (r.bottom - r.top);\r
 \r
                     // Arbitrary threshold, surely keyboard would take more than 20 pix.\r
-                    if (diff < 20)\r
+                    if (diff < 20 && keyboardShown)\r
+                    {\r
+                        keyboardShown = false;\r
                         handleKeyboardHidden (view.host);\r
+                    }\r
+\r
+                    if (! keyboardShown && diff > 20)\r
+                        keyboardShown = true;\r
                 };\r
+\r
+                private boolean keyboardShown;\r
             };\r
 \r
             private ComponentPeerView view;\r
index 07b77dd931f3c186956af07d08e7ae7478ad1a88..651d63db63bdd2bf53a574bdde786ac927b14169 100644 (file)
@@ -1,15 +1,16 @@
 buildscript {\r
    repositories {\r
-       jcenter()\r
        google()\r
+       jcenter()\r
    }\r
    dependencies {\r
-       classpath 'com.android.tools.build:gradle:3.0.1'\r
+       classpath 'com.android.tools.build:gradle:3.1.1'\r
    }\r
 }\r
 \r
 allprojects {\r
    repositories {\r
+       google()\r
        jcenter()\r
    }\r
 }\r
index 6654a817a24092a7793c22f24c55a1c02dfbc7d4..d384d28fd88d3528bda61f4e6d2103d0ce17e8fe 100644 (file)
@@ -1 +1 @@
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
\ No newline at end of file
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
\ No newline at end of file
index 6bfac45787e66c1c96fcd025241d7c303137fd98..4943fc5b425dfa6d85233ac5a6fbee4892ae3fb7 100644 (file)
@@ -35,7 +35,7 @@ ifeq ($(CONFIG),Debug)
     TARGET_ARCH := -march=native\r
   endif\r
 \r
-  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.2.1 -DJUCE_APP_VERSION_HEX=0x50201 $(shell pkg-config --cflags alsa freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)\r
+  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.3.1 -DJUCE_APP_VERSION_HEX=0x50301 $(shell pkg-config --cflags alsa freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)\r
   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
   JUCE_TARGET_APP := DemoRunner\r
 \r
@@ -56,7 +56,7 @@ ifeq ($(CONFIG),Release)
     TARGET_ARCH := -march=native\r
   endif\r
 \r
-  JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCE_DEMO_RUNNER=1 -DJUCE_UNIT_TESTS=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.2.1 -DJUCE_APP_VERSION_HEX=0x50201 $(shell pkg-config --cflags alsa freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)\r
+  JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCE_DEMO_RUNNER=1 -DJUCE_UNIT_TESTS=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.3.1 -DJUCE_APP_VERSION_HEX=0x50301 $(shell pkg-config --cflags alsa freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)\r
   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
   JUCE_TARGET_APP := DemoRunner\r
 \r
index 7ef6842da0a324a1ae4b2b98d206a73cc1eea48b..c4f0557fcd525f3a65aba33262694edf456dcd7d 100644 (file)
        objectVersion = 46;
        objects = {
 
-               A50061EBC77D3A016AABFCB3 = {isa = PBXBuildFile; fileRef = 2ED744F17B2133AC2EFEE9F9; };
-               886B639B447435FE448C23B9 = {isa = PBXBuildFile; fileRef = ECE30C4CD43873204B4B9E32; };
-               AC12EB87710816D88C3D5638 = {isa = PBXBuildFile; fileRef = 0326AFEA87C4FB4537983A3E; };
-               5C9528020475526C0D988DC4 = {isa = PBXBuildFile; fileRef = 8CE0B384BE015EB8B43E0B8A; };
-               7F1AA503C98CA6C7A871153F = {isa = PBXBuildFile; fileRef = 27F6CB9E660948401CD97669; };
-               C361A1511A2D193F636B3E37 = {isa = PBXBuildFile; fileRef = 6E375899B98954B429B8D932; };
-               50CA3BD6C98BEEE95B753DBC = {isa = PBXBuildFile; fileRef = 49BE37716A9444B3C775E2CD; };
-               B81D3893E01BA6B347A524B4 = {isa = PBXBuildFile; fileRef = 1FFDFDFBE666D3040758AF18; };
-               BEC5794CC1DF5965031123A3 = {isa = PBXBuildFile; fileRef = 29ABFAEC066C2D76532D8536; };
-               DA87B9D062E300CDF0AFAA8A = {isa = PBXBuildFile; fileRef = 6A979C969585431AD3FC1DE7; };
-               081F6F081478DD800689BFC5 = {isa = PBXBuildFile; fileRef = F6B6B627ABFFC981B9814540; };
-               6605A1E541941D5C730707AC = {isa = PBXBuildFile; fileRef = 6439D0C31C1D40CF266B83B6; };
-               658FAD570D61A2D04513C4FE = {isa = PBXBuildFile; fileRef = 3AF57E01B5D87F1DA7810A18; };
-               F0701F95186DA3A40A886DB6 = {isa = PBXBuildFile; fileRef = 04490001D298BA2346FF6189; };
-               37A10508D3F52A5E12CF844C = {isa = PBXBuildFile; fileRef = D4F5D236DB815B7E7F574AE5; };
-               3FBFDD4E6AC25CA9D98A6727 = {isa = PBXBuildFile; fileRef = 67CA33EA3C696DA23150A942; };
-               2DC1C2164642836F0AEA40A8 = {isa = PBXBuildFile; fileRef = 054C82A4C1AB1EBC06ED0C8B; };
-               756A7AB6373D013FF081857B = {isa = PBXBuildFile; fileRef = CB06C0F473344197E379229C; };
-               E93AB2D1FE2B626F8D206477 = {isa = PBXBuildFile; fileRef = 929C87E7E3C0BE332F95BD5E; };
-               17A4AA2C7BD1A5303EF23E4C = {isa = PBXBuildFile; fileRef = 9EB484DB75BF878F807AC137; };
-               73850D87E50FB5196EE6B422 = {isa = PBXBuildFile; fileRef = 4A6D87778399E33A46D3F8D1; };
-               272C981B90E5FCF85FC2B356 = {isa = PBXBuildFile; fileRef = 097E110FC89C469C60690346; };
-               61A2A777A5E2165A58CB7FA1 = {isa = PBXBuildFile; fileRef = 0F3DE7E51F0C8FA40039124C; };
-               3A6BADD63BD2CD4C2A4B8B92 = {isa = PBXBuildFile; fileRef = 26781A9A72E1FDBA098F3DF7; };
-               BF2FAB5969AC733B0329C975 = {isa = PBXBuildFile; fileRef = 9571B95A6DC17D950A3E7927; };
-               FF0E86794C1852BE55EF2DE7 = {isa = PBXBuildFile; fileRef = FA96318BFF18EF22CCD5D2C0; };
-               A22B5F90E70672CBEEDBE4D4 = {isa = PBXBuildFile; fileRef = 4087203F4F8298986FA095CF; };
-               608C0EEE88E50CEB33FD93B0 = {isa = PBXBuildFile; fileRef = CA3C94ECDD8ECB56C7CDAD40; };
-               3B41F9F3BA57A45FDD2CF687 = {isa = PBXBuildFile; fileRef = 14A62E059CCEFF286B2FDC5B; };
-               8A90259D6376541FCCDBF59C = {isa = PBXBuildFile; fileRef = 1A96A352C0EC9618525AF0B7; };
-               32E555692EA88756C8AE33C4 = {isa = PBXBuildFile; fileRef = C4ADFA88BEBEA08666061564; };
-               B6158CAAC9D313E28AC0DF0D = {isa = PBXBuildFile; fileRef = 3A947DDFC32557DF9382998A; };
-               1E614F5E3EC385511F4230C4 = {isa = PBXBuildFile; fileRef = 06245F7CFB768425900553E7; };
-               801983262C42D57DC51ACF6B = {isa = PBXBuildFile; fileRef = C4AE3AE69E8A836ED900280D; };
-               F664B60DDB169E8ACA354AF9 = {isa = PBXBuildFile; fileRef = 11CBB5471F59AAE6E49BEFD2; };
-               76D886AA6B0E90D452F10F02 = {isa = PBXBuildFile; fileRef = BF0A51F9471E4D76EF835FAA; };
-               F0CB20CC1945DAFF9E561761 = {isa = PBXBuildFile; fileRef = 13D7E942C9E011C021B85BF9; };
-               1E5DFED918A016879F0E4FB6 = {isa = PBXBuildFile; fileRef = 769FFD43EF73DCB4041FCA75; };
-               534602D32BB67E55866BFD6B = {isa = PBXBuildFile; fileRef = D627A26CC3A04157C5D514AF; };
-               B03DADDEC5B4385D509471E8 = {isa = PBXBuildFile; fileRef = A6C9AAF871AEACE8A7825F1E; };
-               3C5CC8F258D9631CBABF41F3 = {isa = PBXBuildFile; fileRef = D50F316F3E0B6A478EB59989; };
-               4AC737FF1A171EF7ED650753 = {isa = PBXBuildFile; fileRef = A85ADFA746A1D9678E00A168; };
-               FFD08F7DE6EE7278D22A4D8D = {isa = PBXBuildFile; fileRef = 3D0011FC57C8B5226D753F92; };
-               0326AFEA87C4FB4537983A3E = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
-               04490001D298BA2346FF6189 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
-               0481B3E625AB0C716608526E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_basics"; path = "../../../../modules/juce_audio_basics"; sourceTree = "SOURCE_ROOT"; };
-               04BD12AE0CE600640E3F489D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SettingsContent.h; path = ../../Source/UI/SettingsContent.h; sourceTree = "SOURCE_ROOT"; };
-               04F8192B4B8F84153D662FC2 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_osc"; path = "../../../../modules/juce_osc"; sourceTree = "SOURCE_ROOT"; };
-               054C82A4C1AB1EBC06ED0C8B = {isa = PBXFileReference; lastKnownFileType = file.icns; name = Icon.icns; path = Icon.icns; sourceTree = "SOURCE_ROOT"; };
-               06245F7CFB768425900553E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_cryptography.mm"; path = "../../JuceLibraryCode/include_juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; };
-               097E110FC89C469C60690346 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MainComponent.cpp; path = ../../Source/UI/MainComponent.cpp; sourceTree = "SOURCE_ROOT"; };
-               0F3DE7E51F0C8FA40039124C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Main.cpp; path = ../../Source/Main.cpp; sourceTree = "SOURCE_ROOT"; };
-               11CBB5471F59AAE6E49BEFD2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_dsp.mm"; path = "../../JuceLibraryCode/include_juce_dsp.mm"; sourceTree = "SOURCE_ROOT"; };
-               13D7E942C9E011C021B85BF9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_graphics.mm"; path = "../../JuceLibraryCode/include_juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; };
-               14A62E059CCEFF286B2FDC5B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_utils.mm"; path = "../../JuceLibraryCode/include_juce_audio_utils.mm"; sourceTree = "SOURCE_ROOT"; };
-               1575D9310DA31818620D1226 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-App.plist"; path = "Info-App.plist"; sourceTree = "SOURCE_ROOT"; };
-               18AAB3D924B310E3E279FC26 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_basics"; path = "../../../../modules/juce_gui_basics"; sourceTree = "SOURCE_ROOT"; };
-               1A96A352C0EC9618525AF0B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_blocks_basics.cpp"; path = "../../JuceLibraryCode/include_juce_blocks_basics.cpp"; sourceTree = "SOURCE_ROOT"; };
-               1FFDFDFBE666D3040758AF18 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
-               251035E70FD4DF8CB47CE11B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_extra"; path = "../../../../modules/juce_gui_extra"; sourceTree = "SOURCE_ROOT"; };
-               26781A9A72E1FDBA098F3DF7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_analytics.cpp"; path = "../../JuceLibraryCode/include_juce_analytics.cpp"; sourceTree = "SOURCE_ROOT"; };
-               26B6BE6368825BDC47A25EF0 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_cryptography"; path = "../../../../modules/juce_cryptography"; sourceTree = "SOURCE_ROOT"; };
-               27F6CB9E660948401CD97669 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; };
-               29ABFAEC066C2D76532D8536 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
-               2ED744F17B2133AC2EFEE9F9 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoRunner.app; sourceTree = "BUILT_PRODUCTS_DIR"; };
-               3A947DDFC32557DF9382998A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_core.mm"; path = "../../JuceLibraryCode/include_juce_core.mm"; sourceTree = "SOURCE_ROOT"; };
-               3AF57E01B5D87F1DA7810A18 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
-               3D0011FC57C8B5226D753F92 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_video.mm"; path = "../../JuceLibraryCode/include_juce_video.mm"; sourceTree = "SOURCE_ROOT"; };
-               4087203F4F8298986FA095CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_formats.mm"; path = "../../JuceLibraryCode/include_juce_audio_formats.mm"; sourceTree = "SOURCE_ROOT"; };
-               4635F50C3A84562B3846D885 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_devices"; path = "../../../../modules/juce_audio_devices"; sourceTree = "SOURCE_ROOT"; };
-               49BE37716A9444B3C775E2CD = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
-               4A6D87778399E33A46D3F8D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DemoContentComponent.cpp; path = ../../Source/UI/DemoContentComponent.cpp; sourceTree = "SOURCE_ROOT"; };
-               4E8B6E7BD608C8BAB3D34E5E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_utils"; path = "../../../../modules/juce_audio_utils"; sourceTree = "SOURCE_ROOT"; };
-               5043B6C9ED9A1A340C7F13EF = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_formats"; path = "../../../../modules/juce_audio_formats"; sourceTree = "SOURCE_ROOT"; };
-               563422D82232DCEF5C4750FB = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_analytics"; path = "../../../../modules/juce_analytics"; sourceTree = "SOURCE_ROOT"; };
-               5E2942A56F119F3C7A68EC27 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_box2d"; path = "../../../../modules/juce_box2d"; sourceTree = "SOURCE_ROOT"; };
-               5E797E3AE76E4638F96F57ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JUCEDemos.h; path = ../../Source/Demos/JUCEDemos.h; sourceTree = "SOURCE_ROOT"; };
-               63E6F3607FC65720942EC5EF = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_product_unlocking"; path = "../../../../modules/juce_product_unlocking"; sourceTree = "SOURCE_ROOT"; };
-               6439D0C31C1D40CF266B83B6 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
-               64F96A9995CAA940ECA9CE79 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_video"; path = "../../../../modules/juce_video"; sourceTree = "SOURCE_ROOT"; };
-               66B6C67613E5B479E528AEA9 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_data_structures"; path = "../../../../modules/juce_data_structures"; sourceTree = "SOURCE_ROOT"; };
-               67CA33EA3C696DA23150A942 = {isa = PBXFileReference; lastKnownFileType = file.nib; name = RecentFilesMenuTemplate.nib; path = RecentFilesMenuTemplate.nib; sourceTree = "SOURCE_ROOT"; };
-               6A979C969585431AD3FC1DE7 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
-               6E16E438CD7F913C4FCC466C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; };
-               6E375899B98954B429B8D932 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
-               769FFD43EF73DCB4041FCA75 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_basics.mm"; path = "../../JuceLibraryCode/include_juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; };
-               779385E9110DED1036B6DD87 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_processors"; path = "../../../../modules/juce_audio_processors"; sourceTree = "SOURCE_ROOT"; };
-               7A4EF0463F65419994870CF8 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_opengl"; path = "../../../../modules/juce_opengl"; sourceTree = "SOURCE_ROOT"; };
-               7D3B7614BDF9DFBD3204A98B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_dsp"; path = "../../../../modules/juce_dsp"; sourceTree = "SOURCE_ROOT"; };
-               86136E61D36EA0371D61DA88 = {isa = PBXFileReference; lastKnownFileType = image.png; name = JUCEAppIcon.png; path = ../../Source/JUCEAppIcon.png; sourceTree = "SOURCE_ROOT"; };
-               8CE0B384BE015EB8B43E0B8A = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
-               8DD853F21171698ECF027383 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DemoContentComponent.h; path = ../../Source/UI/DemoContentComponent.h; sourceTree = "SOURCE_ROOT"; };
-               929C87E7E3C0BE332F95BD5E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DemoPIPs2.cpp; path = ../../Source/Demos/DemoPIPs2.cpp; sourceTree = "SOURCE_ROOT"; };
-               9571B95A6DC17D950A3E7927 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_basics.mm"; path = "../../JuceLibraryCode/include_juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; };
-               9EB484DB75BF878F807AC137 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = JUCEDemos.cpp; path = ../../Source/Demos/JUCEDemos.cpp; sourceTree = "SOURCE_ROOT"; };
-               9F3EC9807829FC79CB8CD957 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_blocks_basics"; path = "../../../../modules/juce_blocks_basics"; sourceTree = "SOURCE_ROOT"; };
-               A2B31FC014B1F1A8B4EBE44B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_events"; path = "../../../../modules/juce_events"; sourceTree = "SOURCE_ROOT"; };
-               A6C9AAF871AEACE8A7825F1E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_opengl.mm"; path = "../../JuceLibraryCode/include_juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; };
-               A85ADFA746A1D9678E00A168 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_product_unlocking.mm"; path = "../../JuceLibraryCode/include_juce_product_unlocking.mm"; sourceTree = "SOURCE_ROOT"; };
-               B2AFD70A87FA31DC08B38DA7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; };
-               B40D157D83FA7723FC469D74 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_core"; path = "../../../../modules/juce_core"; sourceTree = "SOURCE_ROOT"; };
-               BF0A51F9471E4D76EF835FAA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_events.mm"; path = "../../JuceLibraryCode/include_juce_events.mm"; sourceTree = "SOURCE_ROOT"; };
-               BFFD2BA0FA2CD7A91A4A8F60 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IntroScreen.h; path = ../../Source/Demos/IntroScreen.h; sourceTree = "SOURCE_ROOT"; };
-               C4ADFA88BEBEA08666061564 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_box2d.cpp"; path = "../../JuceLibraryCode/include_juce_box2d.cpp"; sourceTree = "SOURCE_ROOT"; };
-               C4AE3AE69E8A836ED900280D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_data_structures.mm"; path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
-               CA3C94ECDD8ECB56C7CDAD40 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_processors.mm"; path = "../../JuceLibraryCode/include_juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; };
-               CB06C0F473344197E379229C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DemoPIPs1.cpp; path = ../../Source/Demos/DemoPIPs1.cpp; sourceTree = "SOURCE_ROOT"; };
-               D4F5D236DB815B7E7F574AE5 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
-               D50F316F3E0B6A478EB59989 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_osc.cpp"; path = "../../JuceLibraryCode/include_juce_osc.cpp"; sourceTree = "SOURCE_ROOT"; };
-               D627A26CC3A04157C5D514AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_extra.mm"; path = "../../JuceLibraryCode/include_juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; };
-               E95BB1D476BE36D1A6AD7F7E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_graphics"; path = "../../../../modules/juce_graphics"; sourceTree = "SOURCE_ROOT"; };
-               ECE30C4CD43873204B4B9E32 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
-               F6B6B627ABFFC981B9814540 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiscRecording.framework; path = System/Library/Frameworks/DiscRecording.framework; sourceTree = SDKROOT; };
-               FA96318BFF18EF22CCD5D2C0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_devices.mm"; path = "../../JuceLibraryCode/include_juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; };
-               FC235E64CF9B125F89DEE9A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MainComponent.h; path = ../../Source/UI/MainComponent.h; sourceTree = "SOURCE_ROOT"; };
-               4E55327B63E34F22FA7D6C10 = {isa = PBXGroup; children = (
-                                       CB06C0F473344197E379229C,
-                                       929C87E7E3C0BE332F95BD5E,
-                                       BFFD2BA0FA2CD7A91A4A8F60,
-                                       9EB484DB75BF878F807AC137,
-                                       5E797E3AE76E4638F96F57ED, ); name = Demos; sourceTree = "<group>"; };
-               BAB989491CF1D9747AEC0688 = {isa = PBXGroup; children = (
-                                       4A6D87778399E33A46D3F8D1,
-                                       8DD853F21171698ECF027383,
-                                       097E110FC89C469C60690346,
-                                       FC235E64CF9B125F89DEE9A3,
-                                       04BD12AE0CE600640E3F489D, ); name = UI; sourceTree = "<group>"; };
-               7F8CAA66A1D07FBC72E0F95F = {isa = PBXGroup; children = (
-                                       4E55327B63E34F22FA7D6C10,
-                                       BAB989491CF1D9747AEC0688,
-                                       0F3DE7E51F0C8FA40039124C,
-                                       86136E61D36EA0371D61DA88, ); name = Source; sourceTree = "<group>"; };
-               8A320092FEC850844C33A1D6 = {isa = PBXGroup; children = (
-                                       7F8CAA66A1D07FBC72E0F95F, ); name = DemoRunner; sourceTree = "<group>"; };
-               353089C68F5C428ECD9E60A4 = {isa = PBXGroup; children = (
-                                       563422D82232DCEF5C4750FB,
-                                       0481B3E625AB0C716608526E,
-                                       4635F50C3A84562B3846D885,
-                                       5043B6C9ED9A1A340C7F13EF,
-                                       779385E9110DED1036B6DD87,
-                                       4E8B6E7BD608C8BAB3D34E5E,
-                                       9F3EC9807829FC79CB8CD957,
-                                       5E2942A56F119F3C7A68EC27,
-                                       B40D157D83FA7723FC469D74,
-                                       26B6BE6368825BDC47A25EF0,
-                                       66B6C67613E5B479E528AEA9,
-                                       7D3B7614BDF9DFBD3204A98B,
-                                       A2B31FC014B1F1A8B4EBE44B,
-                                       E95BB1D476BE36D1A6AD7F7E,
-                                       18AAB3D924B310E3E279FC26,
-                                       251035E70FD4DF8CB47CE11B,
-                                       7A4EF0463F65419994870CF8,
-                                       04F8192B4B8F84153D662FC2,
-                                       63E6F3607FC65720942EC5EF,
-                                       64F96A9995CAA940ECA9CE79, ); name = "JUCE Modules"; sourceTree = "<group>"; };
-               65D8429D8521FB2026D340E3 = {isa = PBXGroup; children = (
-                                       B2AFD70A87FA31DC08B38DA7,
-                                       26781A9A72E1FDBA098F3DF7,
-                                       9571B95A6DC17D950A3E7927,
-                                       FA96318BFF18EF22CCD5D2C0,
-                                       4087203F4F8298986FA095CF,
-                                       CA3C94ECDD8ECB56C7CDAD40,
-                                       14A62E059CCEFF286B2FDC5B,
-                                       1A96A352C0EC9618525AF0B7,
-                                       C4ADFA88BEBEA08666061564,
-                                       3A947DDFC32557DF9382998A,
-                                       06245F7CFB768425900553E7,
-                                       C4AE3AE69E8A836ED900280D,
-                                       11CBB5471F59AAE6E49BEFD2,
-                                       BF0A51F9471E4D76EF835FAA,
-                                       13D7E942C9E011C021B85BF9,
-                                       769FFD43EF73DCB4041FCA75,
-                                       D627A26CC3A04157C5D514AF,
-                                       A6C9AAF871AEACE8A7825F1E,
-                                       D50F316F3E0B6A478EB59989,
-                                       A85ADFA746A1D9678E00A168,
-                                       3D0011FC57C8B5226D753F92,
-                                       6E16E438CD7F913C4FCC466C, ); name = "JUCE Library Code"; sourceTree = "<group>"; };
-               D2567B3F9EE06A8DB02822E1 = {isa = PBXGroup; children = (
-                                       1575D9310DA31818620D1226,
-                                       67CA33EA3C696DA23150A942,
-                                       054C82A4C1AB1EBC06ED0C8B, ); name = Resources; sourceTree = "<group>"; };
-               472A17EE8274BF9716190070 = {isa = PBXGroup; children = (
-                                       ECE30C4CD43873204B4B9E32,
-                                       0326AFEA87C4FB4537983A3E,
-                                       8CE0B384BE015EB8B43E0B8A,
-                                       27F6CB9E660948401CD97669,
-                                       6E375899B98954B429B8D932,
-                                       49BE37716A9444B3C775E2CD,
-                                       1FFDFDFBE666D3040758AF18,
-                                       29ABFAEC066C2D76532D8536,
-                                       6A979C969585431AD3FC1DE7,
-                                       F6B6B627ABFFC981B9814540,
-                                       6439D0C31C1D40CF266B83B6,
-                                       3AF57E01B5D87F1DA7810A18,
-                                       04490001D298BA2346FF6189,
-                                       D4F5D236DB815B7E7F574AE5, ); name = Frameworks; sourceTree = "<group>"; };
-               53B1E8BA690225D0DCC7118A = {isa = PBXGroup; children = (
-                                       2ED744F17B2133AC2EFEE9F9, ); name = Products; sourceTree = "<group>"; };
-               12C3AAFF06FB271063BD3774 = {isa = PBXGroup; children = (
-                                       8A320092FEC850844C33A1D6,
-                                       353089C68F5C428ECD9E60A4,
-                                       65D8429D8521FB2026D340E3,
-                                       D2567B3F9EE06A8DB02822E1,
-                                       472A17EE8274BF9716190070,
-                                       53B1E8BA690225D0DCC7118A, ); name = Source; sourceTree = "<group>"; };
-               0BF6FF13ABD310AA426C4D86 = {isa = XCBuildConfiguration; buildSettings = {
+               5665A011C7D125C8890D3260 = {isa = PBXBuildFile; fileRef = B953F5C249804F38B818AD2F; };
+               C8D093204643DE75CAA41A3F = {isa = PBXBuildFile; fileRef = E622C086CB768052D799CB95; };
+               7286A5BB489F25E6E3CF63D4 = {isa = PBXBuildFile; fileRef = A70E204AA2B7B904F9C08770; };
+               B6AB4CB9F0A0AD540028A3E1 = {isa = PBXBuildFile; fileRef = F10017EB39A3981DF2FFC565; };
+               71F90E5ABB1112D2D92EAB59 = {isa = PBXBuildFile; fileRef = 61BF1C5B6EB2C49337A028E7; };
+               30F8D005CCE03386DF30747F = {isa = PBXBuildFile; fileRef = 9647BC3EC0BFC192CD7D0643; };
+               C3ECBDFA83E3472AC36AAB1E = {isa = PBXBuildFile; fileRef = A65A103C9FA300E4AEF04066; };
+               AB53895F1E4193A2C9B51DB6 = {isa = PBXBuildFile; fileRef = 5AB31D4FDB61420CFE50FD52; };
+               2EF15A7E6ECFD861D719276A = {isa = PBXBuildFile; fileRef = BE800C80B08E6D722CACB487; };
+               9318D1152DE35146100C7594 = {isa = PBXBuildFile; fileRef = 95C3EC76835BB2151FA94A67; };
+               3AB93979B46C801A20E974C3 = {isa = PBXBuildFile; fileRef = 6D190D5FCC9592AB2135AC75; };
+               4A58CC8B8AEEF166B0E47D37 = {isa = PBXBuildFile; fileRef = BC2C11F10F5D2FB30550C95A; };
+               271D3EB069D6E01D56460721 = {isa = PBXBuildFile; fileRef = DB13FF3C61C11971D3D61C9B; };
+               3D2D1CCFB4B682162034225E = {isa = PBXBuildFile; fileRef = 6142F838E6568F8450BC93DB; };
+               AA910CD1304B21E21D30A37E = {isa = PBXBuildFile; fileRef = 8EACCB8CF4A520630C49BF8A; };
+               83BBBA16872A378CE2E35A9D = {isa = PBXBuildFile; fileRef = 8AC905F72A76E7D7275201A4; };
+               F657E50CA75FE6932E710CB0 = {isa = PBXBuildFile; fileRef = 2945A953347C882A8294DF82; };
+               F9EDB3A8F55A4499441401D6 = {isa = PBXBuildFile; fileRef = AE5650194191C6A04F0B5685; };
+               EACB962CC04BDC0369264A8F = {isa = PBXBuildFile; fileRef = 48A8B50CEB577DF7D3FCEFEC; };
+               557BA8FDD37630DF5EB84EE0 = {isa = PBXBuildFile; fileRef = 5FE974D1CE11D7658D57C580; };
+               5CFCACD6AF608BDC2E1E8BD1 = {isa = PBXBuildFile; fileRef = E40C7EC0CD57D5F92EC9C806; };
+               9263171BCE90616A9F350405 = {isa = PBXBuildFile; fileRef = 56280EAEBEAF619C3E98B5C6; };
+               2EF49BC29DA0951B1C43070F = {isa = PBXBuildFile; fileRef = 27FB5D78BF900B70101B3E48; };
+               8861132DCB0DE3F9EB0DD278 = {isa = PBXBuildFile; fileRef = BD545E9E8BA9D67A673AC8E8; };
+               CCDAEA12C17058099252FD3D = {isa = PBXBuildFile; fileRef = 44B4D9F7DBB239B6E57BC2E7; };
+               28778136A8C09DBDC980CB72 = {isa = PBXBuildFile; fileRef = 2CC2281747C1FE9EB940BD1A; };
+               DA696766645C964870153095 = {isa = PBXBuildFile; fileRef = F996277A397F3F21763BAC03; };
+               8F5FE1B5D44F55667509BC99 = {isa = PBXBuildFile; fileRef = 91195E76A94C136774686D97; };
+               3656169644FED0C525D5D30C = {isa = PBXBuildFile; fileRef = 3290EFAFF391EE790FF33FB9; };
+               2763512B6DFF68C0EEF72496 = {isa = PBXBuildFile; fileRef = 46A8BE3E064F7E01EF1E2D2D; };
+               480F45A17B4E83A26B1ACEF9 = {isa = PBXBuildFile; fileRef = 1442C6A9928B564A86D1597A; };
+               3D8EECDED13F0A46A6FA8D3E = {isa = PBXBuildFile; fileRef = 9A35450231D4C3F4DCF16AB3; };
+               E433C1C591D091AF71AD528E = {isa = PBXBuildFile; fileRef = 55479FCC6DB5293B12918CBA; };
+               A5F8F9904580960794429360 = {isa = PBXBuildFile; fileRef = 9733178D30027A7CC3E12510; };
+               B298295E61E5DD800B814DAF = {isa = PBXBuildFile; fileRef = 7445067DFFF67F28456DA9B0; };
+               A7E206DD280DC58E2A150642 = {isa = PBXBuildFile; fileRef = 1EF8C1691168417E42DF81ED; };
+               26260D259EFF13BD5044CD34 = {isa = PBXBuildFile; fileRef = 120B5B68C50C2992969E9CE1; };
+               591D5799ED6524DE9BD846D7 = {isa = PBXBuildFile; fileRef = 0996038E1E70A6ADD233418D; };
+               D09859BDBC491A9932637715 = {isa = PBXBuildFile; fileRef = 96FE3B2079CA29C6C2F5E2F2; };
+               7EC8A06F9290B16DFB16E346 = {isa = PBXBuildFile; fileRef = A477616D8A134C6E99C2BE9D; };
+               33C96917E46535D30B17B483 = {isa = PBXBuildFile; fileRef = 5F79F2C9508D0D7F5A6BF62D; };
+               8AA7BB967216BDBFF0371267 = {isa = PBXBuildFile; fileRef = 6B2332953FCDD3BD197E149A; };
+               FD5B59B8A0B8258531421E60 = {isa = PBXBuildFile; fileRef = F4AB4BBB26E536232D27BE83; };
+               0996038E1E70A6ADD233418D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_basics.mm"; path = "../../JuceLibraryCode/include_juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; };
+               09AFF79B4D5593574507F03E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_utils"; path = "../../../../modules/juce_audio_utils"; sourceTree = "SOURCE_ROOT"; };
+               0D328B4591EBFD9997C61535 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_product_unlocking"; path = "../../../../modules/juce_product_unlocking"; sourceTree = "SOURCE_ROOT"; };
+               120B5B68C50C2992969E9CE1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_graphics.mm"; path = "../../JuceLibraryCode/include_juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; };
+               1442C6A9928B564A86D1597A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_box2d.cpp"; path = "../../JuceLibraryCode/include_juce_box2d.cpp"; sourceTree = "SOURCE_ROOT"; };
+               18C1EBA9CB73E8E7389BBDCC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; };
+               191B33D36B749639B0FBE856 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MainComponent.h; path = ../../Source/UI/MainComponent.h; sourceTree = "SOURCE_ROOT"; };
+               1EF8C1691168417E42DF81ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_events.mm"; path = "../../JuceLibraryCode/include_juce_events.mm"; sourceTree = "SOURCE_ROOT"; };
+               27FB5D78BF900B70101B3E48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Main.cpp; path = ../../Source/Main.cpp; sourceTree = "SOURCE_ROOT"; };
+               2945A953347C882A8294DF82 = {isa = PBXFileReference; lastKnownFileType = file.icns; name = Icon.icns; path = Icon.icns; sourceTree = "SOURCE_ROOT"; };
+               2CC2281747C1FE9EB940BD1A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_devices.mm"; path = "../../JuceLibraryCode/include_juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; };
+               3290EFAFF391EE790FF33FB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_utils.mm"; path = "../../JuceLibraryCode/include_juce_audio_utils.mm"; sourceTree = "SOURCE_ROOT"; };
+               3384C796C682AF43B57B42F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JUCEDemos.h; path = ../../Source/Demos/JUCEDemos.h; sourceTree = "SOURCE_ROOT"; };
+               44B4D9F7DBB239B6E57BC2E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_basics.mm"; path = "../../JuceLibraryCode/include_juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; };
+               46A8BE3E064F7E01EF1E2D2D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_blocks_basics.cpp"; path = "../../JuceLibraryCode/include_juce_blocks_basics.cpp"; sourceTree = "SOURCE_ROOT"; };
+               47623ED30F98E053C07A9B11 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_dsp"; path = "../../../../modules/juce_dsp"; sourceTree = "SOURCE_ROOT"; };
+               483FAD2B91F1B2A248684D8D = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_graphics"; path = "../../../../modules/juce_graphics"; sourceTree = "SOURCE_ROOT"; };
+               48A8B50CEB577DF7D3FCEFEC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DemoPIPs2.cpp; path = ../../Source/Demos/DemoPIPs2.cpp; sourceTree = "SOURCE_ROOT"; };
+               497F44004821C9FDC0B1A337 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DemoContentComponent.h; path = ../../Source/UI/DemoContentComponent.h; sourceTree = "SOURCE_ROOT"; };
+               4B2E65945C61CDD81D945CC3 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_analytics"; path = "../../../../modules/juce_analytics"; sourceTree = "SOURCE_ROOT"; };
+               531F8760E51457787457AC3D = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_opengl"; path = "../../../../modules/juce_opengl"; sourceTree = "SOURCE_ROOT"; };
+               53ED8C56ECA0B933135E6ED5 = {isa = PBXFileReference; lastKnownFileType = image.png; name = JUCEAppIcon.png; path = ../../Source/JUCEAppIcon.png; sourceTree = "SOURCE_ROOT"; };
+               55479FCC6DB5293B12918CBA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_cryptography.mm"; path = "../../JuceLibraryCode/include_juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; };
+               56280EAEBEAF619C3E98B5C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MainComponent.cpp; path = ../../Source/UI/MainComponent.cpp; sourceTree = "SOURCE_ROOT"; };
+               5AB31D4FDB61420CFE50FD52 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
+               5F79F2C9508D0D7F5A6BF62D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_osc.cpp"; path = "../../JuceLibraryCode/include_juce_osc.cpp"; sourceTree = "SOURCE_ROOT"; };
+               5FE974D1CE11D7658D57C580 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = JUCEDemos.cpp; path = ../../Source/Demos/JUCEDemos.cpp; sourceTree = "SOURCE_ROOT"; };
+               6142F838E6568F8450BC93DB = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+               61BF1C5B6EB2C49337A028E7 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; };
+               62B6BD963ACD31048A939441 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_devices"; path = "../../../../modules/juce_audio_devices"; sourceTree = "SOURCE_ROOT"; };
+               6B2332953FCDD3BD197E149A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_product_unlocking.mm"; path = "../../JuceLibraryCode/include_juce_product_unlocking.mm"; sourceTree = "SOURCE_ROOT"; };
+               6D190D5FCC9592AB2135AC75 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiscRecording.framework; path = System/Library/Frameworks/DiscRecording.framework; sourceTree = SDKROOT; };
+               7445067DFFF67F28456DA9B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_dsp.mm"; path = "../../JuceLibraryCode/include_juce_dsp.mm"; sourceTree = "SOURCE_ROOT"; };
+               74E8AB27C5B4246DA0590820 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IntroScreen.h; path = ../../Source/Demos/IntroScreen.h; sourceTree = "SOURCE_ROOT"; };
+               8AC905F72A76E7D7275201A4 = {isa = PBXFileReference; lastKnownFileType = file.nib; name = RecentFilesMenuTemplate.nib; path = RecentFilesMenuTemplate.nib; sourceTree = "SOURCE_ROOT"; };
+               8DA81A2479F1EF4B1064E3A0 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-App.plist"; path = "Info-App.plist"; sourceTree = "SOURCE_ROOT"; };
+               8EACCB8CF4A520630C49BF8A = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
+               91195E76A94C136774686D97 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_processors.mm"; path = "../../JuceLibraryCode/include_juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; };
+               95C3EC76835BB2151FA94A67 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
+               9647BC3EC0BFC192CD7D0643 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
+               96FE3B2079CA29C6C2F5E2F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_extra.mm"; path = "../../JuceLibraryCode/include_juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; };
+               9733178D30027A7CC3E12510 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_data_structures.mm"; path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
+               9A35450231D4C3F4DCF16AB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_core.mm"; path = "../../JuceLibraryCode/include_juce_core.mm"; sourceTree = "SOURCE_ROOT"; };
+               9A974BD82436ED647B457D0B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_data_structures"; path = "../../../../modules/juce_data_structures"; sourceTree = "SOURCE_ROOT"; };
+               9AA6843063F8D624808AA5FF = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_blocks_basics"; path = "../../../../modules/juce_blocks_basics"; sourceTree = "SOURCE_ROOT"; };
+               9D3C18C7CD24710A9D88CACB = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_osc"; path = "../../../../modules/juce_osc"; sourceTree = "SOURCE_ROOT"; };
+               A075E4A80B931C9431786CB4 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_formats"; path = "../../../../modules/juce_audio_formats"; sourceTree = "SOURCE_ROOT"; };
+               A477616D8A134C6E99C2BE9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_opengl.mm"; path = "../../JuceLibraryCode/include_juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; };
+               A65A103C9FA300E4AEF04066 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+               A70E204AA2B7B904F9C08770 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
+               AE309D5EC9B20A17B819B264 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_processors"; path = "../../../../modules/juce_audio_processors"; sourceTree = "SOURCE_ROOT"; };
+               AE5650194191C6A04F0B5685 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DemoPIPs1.cpp; path = ../../Source/Demos/DemoPIPs1.cpp; sourceTree = "SOURCE_ROOT"; };
+               AE80AC9B628F8B74C6F1F29E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_events"; path = "../../../../modules/juce_events"; sourceTree = "SOURCE_ROOT"; };
+               B953F5C249804F38B818AD2F = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoRunner.app; sourceTree = "BUILT_PRODUCTS_DIR"; };
+               BC2C11F10F5D2FB30550C95A = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
+               BD545E9E8BA9D67A673AC8E8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_analytics.cpp"; path = "../../JuceLibraryCode/include_juce_analytics.cpp"; sourceTree = "SOURCE_ROOT"; };
+               BE800C80B08E6D722CACB487 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
+               BF3AA167B271DBCB79CE3510 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_basics"; path = "../../../../modules/juce_audio_basics"; sourceTree = "SOURCE_ROOT"; };
+               D869E1D6485900AB3406AF03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SettingsContent.h; path = ../../Source/UI/SettingsContent.h; sourceTree = "SOURCE_ROOT"; };
+               D93CFD2601C0E84D357B7959 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_core"; path = "../../../../modules/juce_core"; sourceTree = "SOURCE_ROOT"; };
+               DB13FF3C61C11971D3D61C9B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
+               E40C7EC0CD57D5F92EC9C806 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DemoContentComponent.cpp; path = ../../Source/UI/DemoContentComponent.cpp; sourceTree = "SOURCE_ROOT"; };
+               E4A1F27BDB0FEAB8FD971583 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_box2d"; path = "../../../../modules/juce_box2d"; sourceTree = "SOURCE_ROOT"; };
+               E5CF2486265244CD996876FE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; };
+               E622C086CB768052D799CB95 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
+               ECFF9E66EC18BEAEF2B6C686 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_video"; path = "../../../../modules/juce_video"; sourceTree = "SOURCE_ROOT"; };
+               F10017EB39A3981DF2FFC565 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
+               F124B2F09BEA556820420758 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_basics"; path = "../../../../modules/juce_gui_basics"; sourceTree = "SOURCE_ROOT"; };
+               F3C0C37FD6A1BBBB6588D182 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_extra"; path = "../../../../modules/juce_gui_extra"; sourceTree = "SOURCE_ROOT"; };
+               F4AB4BBB26E536232D27BE83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_video.mm"; path = "../../JuceLibraryCode/include_juce_video.mm"; sourceTree = "SOURCE_ROOT"; };
+               F6E40DCC3B84C97202B9CC21 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_cryptography"; path = "../../../../modules/juce_cryptography"; sourceTree = "SOURCE_ROOT"; };
+               F996277A397F3F21763BAC03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_formats.mm"; path = "../../JuceLibraryCode/include_juce_audio_formats.mm"; sourceTree = "SOURCE_ROOT"; };
+               5F0F17E75142C9F8EC4F9EA8 = {isa = PBXGroup; children = (
+                                       AE5650194191C6A04F0B5685,
+                                       48A8B50CEB577DF7D3FCEFEC,
+                                       74E8AB27C5B4246DA0590820,
+                                       5FE974D1CE11D7658D57C580,
+                                       3384C796C682AF43B57B42F2, ); name = Demos; sourceTree = "<group>"; };
+               C69C98BDBD8901865A10D03D = {isa = PBXGroup; children = (
+                                       E40C7EC0CD57D5F92EC9C806,
+                                       497F44004821C9FDC0B1A337,
+                                       56280EAEBEAF619C3E98B5C6,
+                                       191B33D36B749639B0FBE856,
+                                       D869E1D6485900AB3406AF03, ); name = UI; sourceTree = "<group>"; };
+               29499B4E21D547DC19E2AF25 = {isa = PBXGroup; children = (
+                                       5F0F17E75142C9F8EC4F9EA8,
+                                       C69C98BDBD8901865A10D03D,
+                                       27FB5D78BF900B70101B3E48,
+                                       53ED8C56ECA0B933135E6ED5, ); name = Source; sourceTree = "<group>"; };
+               927472CBD503E38DD7E37090 = {isa = PBXGroup; children = (
+                                       29499B4E21D547DC19E2AF25, ); name = DemoRunner; sourceTree = "<group>"; };
+               178FF737E5519A4D16208DEB = {isa = PBXGroup; children = (
+                                       4B2E65945C61CDD81D945CC3,
+                                       BF3AA167B271DBCB79CE3510,
+                                       62B6BD963ACD31048A939441,
+                                       A075E4A80B931C9431786CB4,
+                                       AE309D5EC9B20A17B819B264,
+                                       09AFF79B4D5593574507F03E,
+                                       9AA6843063F8D624808AA5FF,
+                                       E4A1F27BDB0FEAB8FD971583,
+                                       D93CFD2601C0E84D357B7959,
+                                       F6E40DCC3B84C97202B9CC21,
+                                       9A974BD82436ED647B457D0B,
+                                       47623ED30F98E053C07A9B11,
+                                       AE80AC9B628F8B74C6F1F29E,
+                                       483FAD2B91F1B2A248684D8D,
+                                       F124B2F09BEA556820420758,
+                                       F3C0C37FD6A1BBBB6588D182,
+                                       531F8760E51457787457AC3D,
+                                       9D3C18C7CD24710A9D88CACB,
+                                       0D328B4591EBFD9997C61535,
+                                       ECFF9E66EC18BEAEF2B6C686, ); name = "JUCE Modules"; sourceTree = "<group>"; };
+               16DD35D8533EE0BA94AAFBF8 = {isa = PBXGroup; children = (
+                                       18C1EBA9CB73E8E7389BBDCC,
+                                       BD545E9E8BA9D67A673AC8E8,
+                                       44B4D9F7DBB239B6E57BC2E7,
+                                       2CC2281747C1FE9EB940BD1A,
+                                       F996277A397F3F21763BAC03,
+                                       91195E76A94C136774686D97,
+                                       3290EFAFF391EE790FF33FB9,
+                                       46A8BE3E064F7E01EF1E2D2D,
+                                       1442C6A9928B564A86D1597A,
+                                       9A35450231D4C3F4DCF16AB3,
+                                       55479FCC6DB5293B12918CBA,
+                                       9733178D30027A7CC3E12510,
+                                       7445067DFFF67F28456DA9B0,
+                                       1EF8C1691168417E42DF81ED,
+                                       120B5B68C50C2992969E9CE1,
+                                       0996038E1E70A6ADD233418D,
+                                       96FE3B2079CA29C6C2F5E2F2,
+                                       A477616D8A134C6E99C2BE9D,
+                                       5F79F2C9508D0D7F5A6BF62D,
+                                       6B2332953FCDD3BD197E149A,
+                                       F4AB4BBB26E536232D27BE83,
+                                       E5CF2486265244CD996876FE, ); name = "JUCE Library Code"; sourceTree = "<group>"; };
+               FEE1C6574320FAB66F0238D2 = {isa = PBXGroup; children = (
+                                       8DA81A2479F1EF4B1064E3A0,
+                                       8AC905F72A76E7D7275201A4,
+                                       2945A953347C882A8294DF82, ); name = Resources; sourceTree = "<group>"; };
+               17F11FE561BD8D6EB93B64D4 = {isa = PBXGroup; children = (
+                                       E622C086CB768052D799CB95,
+                                       A70E204AA2B7B904F9C08770,
+                                       F10017EB39A3981DF2FFC565,
+                                       61BF1C5B6EB2C49337A028E7,
+                                       9647BC3EC0BFC192CD7D0643,
+                                       A65A103C9FA300E4AEF04066,
+                                       5AB31D4FDB61420CFE50FD52,
+                                       BE800C80B08E6D722CACB487,
+                                       95C3EC76835BB2151FA94A67,
+                                       6D190D5FCC9592AB2135AC75,
+                                       BC2C11F10F5D2FB30550C95A,
+                                       DB13FF3C61C11971D3D61C9B,
+                                       6142F838E6568F8450BC93DB,
+                                       8EACCB8CF4A520630C49BF8A, ); name = Frameworks; sourceTree = "<group>"; };
+               532CECDAA91A39864E7FFF80 = {isa = PBXGroup; children = (
+                                       B953F5C249804F38B818AD2F, ); name = Products; sourceTree = "<group>"; };
+               9979C8B054ED17C9E04C6BAB = {isa = PBXGroup; children = (
+                                       927472CBD503E38DD7E37090,
+                                       178FF737E5519A4D16208DEB,
+                                       16DD35D8533EE0BA94AAFBF8,
+                                       FEE1C6574320FAB66F0238D2,
+                                       17F11FE561BD8D6EB93B64D4,
+                                       532CECDAA91A39864E7FFF80, ); name = Source; sourceTree = "<group>"; };
+               CEC200AA273D1626F466FC27 = {isa = XCBuildConfiguration; buildSettings = {
                                CLANG_CXX_LANGUAGE_STANDARD = "c++14";
                                CLANG_LINK_OBJC_RUNTIME = NO;
                                COMBINE_HIDPI_IMAGES = YES;
                                        "JUCE_DEMO_RUNNER=1",
                                        "JUCE_UNIT_TESTS=1",
                                        "JUCER_XCODE_MAC_F6D2F4CF=1",
-                                       "JUCE_APP_VERSION=5.2.1",
-                                       "JUCE_APP_VERSION_HEX=0x50201",
+                                       "JUCE_APP_VERSION=5.3.1",
+                                       "JUCE_APP_VERSION_HEX=0x50301",
                                        "JucePlugin_Build_VST=0",
                                        "JucePlugin_Build_VST3=0",
                                        "JucePlugin_Build_AU=0",
                                INSTALL_PATH = "$(HOME)/Applications";
                                MACOSX_DEPLOYMENT_TARGET = 10.11;
                                MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
+                               OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -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 -Wno-ignored-qualifiers -Wunreachable-code";
                                PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.demorunner;
                                SDKROOT_ppc = macosx10.5;
                                USE_HEADERMAP = NO; }; name = Debug; };
-               AAA32DF950DBB34322AB0692 = {isa = XCBuildConfiguration; buildSettings = {
+               878F062DF0F2D968EC322CF4 = {isa = XCBuildConfiguration; buildSettings = {
                                CLANG_CXX_LANGUAGE_STANDARD = "c++14";
                                CLANG_LINK_OBJC_RUNTIME = NO;
                                COMBINE_HIDPI_IMAGES = YES;
                                        "JUCE_DEMO_RUNNER=1",
                                        "JUCE_UNIT_TESTS=1",
                                        "JUCER_XCODE_MAC_F6D2F4CF=1",
-                                       "JUCE_APP_VERSION=5.2.1",
-                                       "JUCE_APP_VERSION_HEX=0x50201",
+                                       "JUCE_APP_VERSION=5.3.1",
+                                       "JUCE_APP_VERSION_HEX=0x50301",
                                        "JucePlugin_Build_VST=0",
                                        "JucePlugin_Build_VST3=0",
                                        "JucePlugin_Build_AU=0",
                                LLVM_LTO = YES;
                                MACOSX_DEPLOYMENT_TARGET = 10.11;
                                MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
+                               OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -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 -Wno-ignored-qualifiers -Wunreachable-code";
                                PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.demorunner;
                                SDKROOT_ppc = macosx10.5;
                                USE_HEADERMAP = NO; }; name = Release; };
-               211506D1B60914B8C1546597 = {isa = XCBuildConfiguration; buildSettings = {
+               49CDF00877DBD03D2C6D7313 = {isa = XCBuildConfiguration; buildSettings = {
                                ALWAYS_SEARCH_USER_PATHS = NO;
                                CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
                                CLANG_WARN_BOOL_CONVERSION = YES;
                                PRODUCT_NAME = "DemoRunner";
                                WARNING_CFLAGS = -Wreorder;
                                ZERO_LINK = NO; }; name = Debug; };
-               5B00E3812B10D12D66804140 = {isa = XCBuildConfiguration; buildSettings = {
+               4CADE461B4B845777C2F3084 = {isa = XCBuildConfiguration; buildSettings = {
                                ALWAYS_SEARCH_USER_PATHS = NO;
                                CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
                                CLANG_WARN_BOOL_CONVERSION = YES;
                                PRODUCT_NAME = "DemoRunner";
                                WARNING_CFLAGS = -Wreorder;
                                ZERO_LINK = NO; }; name = Release; };
-               8FFD14978945B15A63DA441C = {isa = PBXTargetDependency; target = 5C44D3B98501718D937EAA8C; };
-               E7D42B7F81AAAB7DE49DAE20 = {isa = XCConfigurationList; buildConfigurations = (
-                                       211506D1B60914B8C1546597,
-                                       5B00E3812B10D12D66804140, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
-               D8423C9D12EDCA5569929D2C = {isa = XCConfigurationList; buildConfigurations = (
-                                       0BF6FF13ABD310AA426C4D86,
-                                       AAA32DF950DBB34322AB0692, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
-               EB12964B44C1C7B6159FB179 = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (
-                                       3FBFDD4E6AC25CA9D98A6727,
-                                       2DC1C2164642836F0AEA40A8, ); runOnlyForDeploymentPostprocessing = 0; };
-               D7CEBDA9ACAE974C9C78903D = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (
-                                       756A7AB6373D013FF081857B,
-                                       E93AB2D1FE2B626F8D206477,
-                                       17A4AA2C7BD1A5303EF23E4C,
-                                       73850D87E50FB5196EE6B422,
-                                       272C981B90E5FCF85FC2B356,
-                                       61A2A777A5E2165A58CB7FA1,
-                                       3A6BADD63BD2CD4C2A4B8B92,
-                                       BF2FAB5969AC733B0329C975,
-                                       FF0E86794C1852BE55EF2DE7,
-                                       A22B5F90E70672CBEEDBE4D4,
-                                       608C0EEE88E50CEB33FD93B0,
-                                       3B41F9F3BA57A45FDD2CF687,
-                                       8A90259D6376541FCCDBF59C,
-                                       32E555692EA88756C8AE33C4,
-                                       B6158CAAC9D313E28AC0DF0D,
-                                       1E614F5E3EC385511F4230C4,
-                                       801983262C42D57DC51ACF6B,
-                                       F664B60DDB169E8ACA354AF9,
-                                       76D886AA6B0E90D452F10F02,
-                                       F0CB20CC1945DAFF9E561761,
-                                       1E5DFED918A016879F0E4FB6,
-                                       534602D32BB67E55866BFD6B,
-                                       B03DADDEC5B4385D509471E8,
-                                       3C5CC8F258D9631CBABF41F3,
-                                       4AC737FF1A171EF7ED650753,
-                                       FFD08F7DE6EE7278D22A4D8D, ); runOnlyForDeploymentPostprocessing = 0; };
-               FC5B047114D0B62045C1432E = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (
-                                       886B639B447435FE448C23B9,
-                                       AC12EB87710816D88C3D5638,
-                                       5C9528020475526C0D988DC4,
-                                       7F1AA503C98CA6C7A871153F,
-                                       C361A1511A2D193F636B3E37,
-                                       50CA3BD6C98BEEE95B753DBC,
-                                       B81D3893E01BA6B347A524B4,
-                                       BEC5794CC1DF5965031123A3,
-                                       DA87B9D062E300CDF0AFAA8A,
-                                       081F6F081478DD800689BFC5,
-                                       6605A1E541941D5C730707AC,
-                                       658FAD570D61A2D04513C4FE,
-                                       F0701F95186DA3A40A886DB6,
-                                       37A10508D3F52A5E12CF844C, ); runOnlyForDeploymentPostprocessing = 0; };
-               5C44D3B98501718D937EAA8C = {isa = PBXNativeTarget; buildConfigurationList = D8423C9D12EDCA5569929D2C; buildPhases = (
-                                       EB12964B44C1C7B6159FB179,
-                                       D7CEBDA9ACAE974C9C78903D,
-                                       FC5B047114D0B62045C1432E, ); buildRules = ( ); dependencies = (  ); name = "DemoRunner - App"; productName = DemoRunner; productReference = 2ED744F17B2133AC2EFEE9F9; productType = "com.apple.product-type.application"; };
-               1658833C7B558CFD9996D813 = {isa = PBXProject; buildConfigurationList = E7D42B7F81AAAB7DE49DAE20; attributes = { LastUpgradeCheck = 0830; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { 5C44D3B98501718D937EAA8C = { 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; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 12C3AAFF06FB271063BD3774; projectDirPath = ""; projectRoot = ""; targets = (5C44D3B98501718D937EAA8C); };
+               82C712E3A2B72D3FE08871AB = {isa = PBXTargetDependency; target = AF4A5EF10D3A095A9074F9CF; };
+               F63BE64D6F90B83AFFFBC14F = {isa = XCConfigurationList; buildConfigurations = (
+                                       49CDF00877DBD03D2C6D7313,
+                                       4CADE461B4B845777C2F3084, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
+               77311CC6EFE85E7117AD3242 = {isa = XCConfigurationList; buildConfigurations = (
+                                       CEC200AA273D1626F466FC27,
+                                       878F062DF0F2D968EC322CF4, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
+               2077585B61D41BDA5967E25C = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (
+                                       83BBBA16872A378CE2E35A9D,
+                                       F657E50CA75FE6932E710CB0, ); runOnlyForDeploymentPostprocessing = 0; };
+               7C6E2E57520A67ACFE86097B = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (
+                                       F9EDB3A8F55A4499441401D6,
+                                       EACB962CC04BDC0369264A8F,
+                                       557BA8FDD37630DF5EB84EE0,
+                                       5CFCACD6AF608BDC2E1E8BD1,
+                                       9263171BCE90616A9F350405,
+                                       2EF49BC29DA0951B1C43070F,
+                                       8861132DCB0DE3F9EB0DD278,
+                                       CCDAEA12C17058099252FD3D,
+                                       28778136A8C09DBDC980CB72,
+                                       DA696766645C964870153095,
+                                       8F5FE1B5D44F55667509BC99,
+                                       3656169644FED0C525D5D30C,
+                                       2763512B6DFF68C0EEF72496,
+                                       480F45A17B4E83A26B1ACEF9,
+                                       3D8EECDED13F0A46A6FA8D3E,
+                                       E433C1C591D091AF71AD528E,
+                                       A5F8F9904580960794429360,
+                                       B298295E61E5DD800B814DAF,
+                                       A7E206DD280DC58E2A150642,
+                                       26260D259EFF13BD5044CD34,
+                                       591D5799ED6524DE9BD846D7,
+                                       D09859BDBC491A9932637715,
+                                       7EC8A06F9290B16DFB16E346,
+                                       33C96917E46535D30B17B483,
+                                       8AA7BB967216BDBFF0371267,
+                                       FD5B59B8A0B8258531421E60, ); runOnlyForDeploymentPostprocessing = 0; };
+               FB8E53AB54C36DCB3C3FC501 = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (
+                                       C8D093204643DE75CAA41A3F,
+                                       7286A5BB489F25E6E3CF63D4,
+                                       B6AB4CB9F0A0AD540028A3E1,
+                                       71F90E5ABB1112D2D92EAB59,
+                                       30F8D005CCE03386DF30747F,
+                                       C3ECBDFA83E3472AC36AAB1E,
+                                       AB53895F1E4193A2C9B51DB6,
+                                       2EF15A7E6ECFD861D719276A,
+                                       9318D1152DE35146100C7594,
+                                       3AB93979B46C801A20E974C3,
+                                       4A58CC8B8AEEF166B0E47D37,
+                                       271D3EB069D6E01D56460721,
+                                       3D2D1CCFB4B682162034225E,
+                                       AA910CD1304B21E21D30A37E, ); runOnlyForDeploymentPostprocessing = 0; };
+               AF4A5EF10D3A095A9074F9CF = {isa = PBXNativeTarget; buildConfigurationList = 77311CC6EFE85E7117AD3242; buildPhases = (
+                                       2077585B61D41BDA5967E25C,
+                                       7C6E2E57520A67ACFE86097B,
+                                       FB8E53AB54C36DCB3C3FC501, ); buildRules = ( ); dependencies = (  ); name = "DemoRunner - App"; productName = DemoRunner; productReference = B953F5C249804F38B818AD2F; productType = "com.apple.product-type.application"; };
+               15C553274AB25531D0A16FBE = {isa = PBXProject; buildConfigurationList = F63BE64D6F90B83AFFFBC14F; attributes = { LastUpgradeCheck = 0830; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { AF4A5EF10D3A095A9074F9CF = { 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; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 9979C8B054ED17C9E04C6BAB; projectDirPath = ""; projectRoot = ""; targets = (AF4A5EF10D3A095A9074F9CF); };
        };
-       rootObject = 1658833C7B558CFD9996D813;
+       rootObject = 15C553274AB25531D0A16FBE;
 }
index 7704fc69c7cde4cec8e4eb76b17d020cbd9296ef..39ca56ccb109a27599adb30c2f059d58358ded3b 100644 (file)
@@ -18,9 +18,9 @@
     <key>CFBundleSignature</key>\r
     <string>????</string>\r
     <key>CFBundleShortVersionString</key>\r
-    <string>5.2.1</string>\r
+    <string>5.3.1</string>\r
     <key>CFBundleVersion</key>\r
-    <string>5.2.1</string>\r
+    <string>5.3.1</string>\r
     <key>NSHumanReadableCopyright</key>\r
     <string>Copyright (c) 2018 - ROLI Ltd.</string>\r
     <key>NSHighResolutionCapable</key>\r
index 6209dae17f8afce95475da6064fbd5dc032b75cd..47ffd1f936f097a705667bd1b5709a95fe1fb9d0 100644 (file)
@@ -1,7 +1,7 @@
 Microsoft Visual Studio Solution File, Format Version 11.00\r
 # Visual Studio 2013\r
 \r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DemoRunner - App", "DemoRunner_App.vcxproj", "{19906CE9-09EE-B4FB-5695-178A64D9BBB2}"\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DemoRunner - App", "DemoRunner_App.vcxproj", "{E3D4150A-FA75-0747-0E47-EDA1155AAAFF}"\r
 EndProject\r
 Global\r
        GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
@@ -9,10 +9,10 @@ Global
                Release|x64 = Release|x64\r
        EndGlobalSection\r
        GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
-               {19906CE9-09EE-B4FB-5695-178A64D9BBB2}.Debug|x64.ActiveCfg = Debug|x64\r
-               {19906CE9-09EE-B4FB-5695-178A64D9BBB2}.Debug|x64.Build.0 = Debug|x64\r
-               {19906CE9-09EE-B4FB-5695-178A64D9BBB2}.Release|x64.ActiveCfg = Release|x64\r
-               {19906CE9-09EE-B4FB-5695-178A64D9BBB2}.Release|x64.Build.0 = Release|x64\r
+               {E3D4150A-FA75-0747-0E47-EDA1155AAAFF}.Debug|x64.ActiveCfg = Debug|x64\r
+               {E3D4150A-FA75-0747-0E47-EDA1155AAAFF}.Debug|x64.Build.0 = Debug|x64\r
+               {E3D4150A-FA75-0747-0E47-EDA1155AAAFF}.Release|x64.ActiveCfg = Release|x64\r
+               {E3D4150A-FA75-0747-0E47-EDA1155AAAFF}.Release|x64.Build.0 = Release|x64\r
        EndGlobalSection\r
        GlobalSection(SolutionProperties) = preSolution\r
                HideSolutionNode = FALSE\r
index e73f8e6742f68b255652036866eaae00578a2985..c545c528929b7b9932a4d1a64a095f150d1cfced 100644 (file)
@@ -14,7 +14,7 @@
     </ProjectConfiguration>\r
   </ItemGroup>\r
   <PropertyGroup Label="Globals">\r
-    <ProjectGuid>{19906CE9-09EE-B4FB-5695-178A64D9BBB2}</ProjectGuid>\r
+    <ProjectGuid>{E3D4150A-FA75-0747-0E47-EDA1155AAAFF}</ProjectGuid>\r
     <PlatformToolset>v120</PlatformToolset>\r
     <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\r
   </PropertyGroup>\r
@@ -74,7 +74,7 @@
       <Optimization>Disabled</Optimization>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
       <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=5.2.1;JUCE_APP_VERSION_HEX=0x50201;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=5.3.1;JUCE_APP_VERSION_HEX=0x50301;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
       <PrecompiledHeader/>\r
     <ClCompile>\r
       <Optimization>Full</Optimization>\r
       <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=5.2.1;JUCE_APP_VERSION_HEX=0x50201;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=5.3.1;JUCE_APP_VERSION_HEX=0x50301;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
       <PrecompiledHeader/>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
index 09566e6443adf1fa10abf3770229d8cdd3b31b15..a17949c39260e4e4473dfe06ea783e95a7e43569 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
index 1b61401b932093b4352142d96362d3dd82abf85b..d22ed6117b12b946522bb3c4398a341a897e62d5 100644 (file)
@@ -7,7 +7,7 @@
 #include <windows.h>\r
 \r
 VS_VERSION_INFO VERSIONINFO\r
-FILEVERSION  5,2,1,0\r
+FILEVERSION  5,3,1,0\r
 BEGIN\r
   BLOCK "StringFileInfo"\r
   BEGIN\r
@@ -16,9 +16,9 @@ BEGIN
       VALUE "CompanyName",  "ROLI Ltd.\0"\r
       VALUE "LegalCopyright",  "Copyright (c) 2018 - ROLI Ltd.\0"\r
       VALUE "FileDescription",  "DemoRunner\0"\r
-      VALUE "FileVersion",  "5.2.1\0"\r
+      VALUE "FileVersion",  "5.3.1\0"\r
       VALUE "ProductName",  "DemoRunner\0"\r
-      VALUE "ProductVersion",  "5.2.1\0"\r
+      VALUE "ProductVersion",  "5.3.1\0"\r
     END\r
   END\r
 \r
index f50e4b61ec1794f7332d1af7c07536638b9697c1..fef93e709d989050c3c56a4363d306e5e1816c08 100644 (file)
@@ -1,7 +1,7 @@
 Microsoft Visual Studio Solution File, Format Version 11.00\r
 # Visual Studio 2015\r
 \r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DemoRunner - App", "DemoRunner_App.vcxproj", "{19906CE9-09EE-B4FB-5695-178A64D9BBB2}"\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DemoRunner - App", "DemoRunner_App.vcxproj", "{E3D4150A-FA75-0747-0E47-EDA1155AAAFF}"\r
 EndProject\r
 Global\r
        GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
@@ -9,10 +9,10 @@ Global
                Release|x64 = Release|x64\r
        EndGlobalSection\r
        GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
-               {19906CE9-09EE-B4FB-5695-178A64D9BBB2}.Debug|x64.ActiveCfg = Debug|x64\r
-               {19906CE9-09EE-B4FB-5695-178A64D9BBB2}.Debug|x64.Build.0 = Debug|x64\r
-               {19906CE9-09EE-B4FB-5695-178A64D9BBB2}.Release|x64.ActiveCfg = Release|x64\r
-               {19906CE9-09EE-B4FB-5695-178A64D9BBB2}.Release|x64.Build.0 = Release|x64\r
+               {E3D4150A-FA75-0747-0E47-EDA1155AAAFF}.Debug|x64.ActiveCfg = Debug|x64\r
+               {E3D4150A-FA75-0747-0E47-EDA1155AAAFF}.Debug|x64.Build.0 = Debug|x64\r
+               {E3D4150A-FA75-0747-0E47-EDA1155AAAFF}.Release|x64.ActiveCfg = Release|x64\r
+               {E3D4150A-FA75-0747-0E47-EDA1155AAAFF}.Release|x64.Build.0 = Release|x64\r
        EndGlobalSection\r
        GlobalSection(SolutionProperties) = preSolution\r
                HideSolutionNode = FALSE\r
index f45075fcbebdc4c045797e888ae579301e6b4901..71523961fa56ae8b588267de1755cffd57116908 100644 (file)
@@ -14,7 +14,7 @@
     </ProjectConfiguration>\r
   </ItemGroup>\r
   <PropertyGroup Label="Globals">\r
-    <ProjectGuid>{19906CE9-09EE-B4FB-5695-178A64D9BBB2}</ProjectGuid>\r
+    <ProjectGuid>{E3D4150A-FA75-0747-0E47-EDA1155AAAFF}</ProjectGuid>\r
     <PlatformToolset>v140</PlatformToolset>\r
     <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\r
   </PropertyGroup>\r
@@ -74,7 +74,7 @@
       <Optimization>Disabled</Optimization>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
       <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.2.1;JUCE_APP_VERSION_HEX=0x50201;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.3.1;JUCE_APP_VERSION_HEX=0x50301;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
       <PrecompiledHeader/>\r
     <ClCompile>\r
       <Optimization>Full</Optimization>\r
       <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.2.1;JUCE_APP_VERSION_HEX=0x50201;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.3.1;JUCE_APP_VERSION_HEX=0x50301;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
       <PrecompiledHeader/>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
index daacdae7647eab5a8af912ae492e758f31a5a5ba..fe88ae0055b2baade827dad3036e8509d7457b4e 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
index 1b61401b932093b4352142d96362d3dd82abf85b..d22ed6117b12b946522bb3c4398a341a897e62d5 100644 (file)
@@ -7,7 +7,7 @@
 #include <windows.h>\r
 \r
 VS_VERSION_INFO VERSIONINFO\r
-FILEVERSION  5,2,1,0\r
+FILEVERSION  5,3,1,0\r
 BEGIN\r
   BLOCK "StringFileInfo"\r
   BEGIN\r
@@ -16,9 +16,9 @@ BEGIN
       VALUE "CompanyName",  "ROLI Ltd.\0"\r
       VALUE "LegalCopyright",  "Copyright (c) 2018 - ROLI Ltd.\0"\r
       VALUE "FileDescription",  "DemoRunner\0"\r
-      VALUE "FileVersion",  "5.2.1\0"\r
+      VALUE "FileVersion",  "5.3.1\0"\r
       VALUE "ProductName",  "DemoRunner\0"\r
-      VALUE "ProductVersion",  "5.2.1\0"\r
+      VALUE "ProductVersion",  "5.3.1\0"\r
     END\r
   END\r
 \r
index 4693ac5e3c1e6ce50f9b17d8dc6bd8bf08108832..371c21f38c3d1a1a8e2599f62042de00fd9b13fb 100644 (file)
@@ -1,7 +1,7 @@
 Microsoft Visual Studio Solution File, Format Version 11.00\r
 # Visual Studio 2017\r
 \r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DemoRunner - App", "DemoRunner_App.vcxproj", "{19906CE9-09EE-B4FB-5695-178A64D9BBB2}"\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DemoRunner - App", "DemoRunner_App.vcxproj", "{E3D4150A-FA75-0747-0E47-EDA1155AAAFF}"\r
 EndProject\r
 Global\r
        GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
@@ -9,10 +9,10 @@ Global
                Release|x64 = Release|x64\r
        EndGlobalSection\r
        GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
-               {19906CE9-09EE-B4FB-5695-178A64D9BBB2}.Debug|x64.ActiveCfg = Debug|x64\r
-               {19906CE9-09EE-B4FB-5695-178A64D9BBB2}.Debug|x64.Build.0 = Debug|x64\r
-               {19906CE9-09EE-B4FB-5695-178A64D9BBB2}.Release|x64.ActiveCfg = Release|x64\r
-               {19906CE9-09EE-B4FB-5695-178A64D9BBB2}.Release|x64.Build.0 = Release|x64\r
+               {E3D4150A-FA75-0747-0E47-EDA1155AAAFF}.Debug|x64.ActiveCfg = Debug|x64\r
+               {E3D4150A-FA75-0747-0E47-EDA1155AAAFF}.Debug|x64.Build.0 = Debug|x64\r
+               {E3D4150A-FA75-0747-0E47-EDA1155AAAFF}.Release|x64.ActiveCfg = Release|x64\r
+               {E3D4150A-FA75-0747-0E47-EDA1155AAAFF}.Release|x64.Build.0 = Release|x64\r
        EndGlobalSection\r
        GlobalSection(SolutionProperties) = preSolution\r
                HideSolutionNode = FALSE\r
index b8bb07dbb32eaba7e058efb717345f0729c23219..c340defe8c500d19ec854fbc8549e3c69525e9d0 100644 (file)
@@ -14,7 +14,7 @@
     </ProjectConfiguration>\r
   </ItemGroup>\r
   <PropertyGroup Label="Globals">\r
-    <ProjectGuid>{19906CE9-09EE-B4FB-5695-178A64D9BBB2}</ProjectGuid>\r
+    <ProjectGuid>{E3D4150A-FA75-0747-0E47-EDA1155AAAFF}</ProjectGuid>\r
     <PlatformToolset>v141</PlatformToolset>\r
     <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>\r
   </PropertyGroup>\r
@@ -74,7 +74,7 @@
       <Optimization>Disabled</Optimization>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
       <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.2.1;JUCE_APP_VERSION_HEX=0x50201;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.3.1;JUCE_APP_VERSION_HEX=0x50301;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
       <PrecompiledHeader/>\r
     <ClCompile>\r
       <Optimization>Full</Optimization>\r
       <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.2.1;JUCE_APP_VERSION_HEX=0x50201;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.3.1;JUCE_APP_VERSION_HEX=0x50301;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
       <PrecompiledHeader/>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
index eb12dc0aa7bd9c1ece85c59f426936085d497814..e7ed5a8e0d04a51f8004f2b4fef017de56df71d2 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
index 1b61401b932093b4352142d96362d3dd82abf85b..d22ed6117b12b946522bb3c4398a341a897e62d5 100644 (file)
@@ -7,7 +7,7 @@
 #include <windows.h>\r
 \r
 VS_VERSION_INFO VERSIONINFO\r
-FILEVERSION  5,2,1,0\r
+FILEVERSION  5,3,1,0\r
 BEGIN\r
   BLOCK "StringFileInfo"\r
   BEGIN\r
@@ -16,9 +16,9 @@ BEGIN
       VALUE "CompanyName",  "ROLI Ltd.\0"\r
       VALUE "LegalCopyright",  "Copyright (c) 2018 - ROLI Ltd.\0"\r
       VALUE "FileDescription",  "DemoRunner\0"\r
-      VALUE "FileVersion",  "5.2.1\0"\r
+      VALUE "FileVersion",  "5.3.1\0"\r
       VALUE "ProductName",  "DemoRunner\0"\r
-      VALUE "ProductVersion",  "5.2.1\0"\r
+      VALUE "ProductVersion",  "5.3.1\0"\r
     END\r
   END\r
 \r
index 2961af89ad96bc2daa204ec9a0e0defe6db17a93..0cc6513c1525a3e6c05e37ef1b7760a22a2aa336 100644 (file)
        objectVersion = 46;
        objects = {
 
-               A50061EBC77D3A016AABFCB3 = {isa = PBXBuildFile; fileRef = 2ED744F17B2133AC2EFEE9F9; };
-               886B639B447435FE448C23B9 = {isa = PBXBuildFile; fileRef = ECE30C4CD43873204B4B9E32; };
-               AC12EB87710816D88C3D5638 = {isa = PBXBuildFile; fileRef = 0326AFEA87C4FB4537983A3E; };
-               5C9528020475526C0D988DC4 = {isa = PBXBuildFile; fileRef = 8CE0B384BE015EB8B43E0B8A; };
-               7F1AA503C98CA6C7A871153F = {isa = PBXBuildFile; fileRef = 27F6CB9E660948401CD97669; };
-               B81D3893E01BA6B347A524B4 = {isa = PBXBuildFile; fileRef = 1FFDFDFBE666D3040758AF18; };
-               66CD55F2A348D8A949431DB3 = {isa = PBXBuildFile; fileRef = 4124591B632A530112C2F1D6; };
-               A937D294F46A3C68720BF01A = {isa = PBXBuildFile; fileRef = 655CE61850C4C0BAF8E09DF6; };
-               6C6E157D6B635CEC54EDD4EC = {isa = PBXBuildFile; fileRef = B750A664A1E944AD116626FE; };
-               BEC5794CC1DF5965031123A3 = {isa = PBXBuildFile; fileRef = 29ABFAEC066C2D76532D8536; };
-               DA87B9D062E300CDF0AFAA8A = {isa = PBXBuildFile; fileRef = 6A979C969585431AD3FC1DE7; };
-               9857BBAEFF58ABFDD46170F3 = {isa = PBXBuildFile; fileRef = E9BDE77C1EB97BBEE49D013A; };
-               BB5AADC46D641EB6C2EDD6C3 = {isa = PBXBuildFile; fileRef = DC46EC2AEC1139B659B5DF05; };
-               14DE1ECE2F55AE0896428FFF = {isa = PBXBuildFile; fileRef = 7D342958D0DBE535A3D275A0; };
-               315180ECB6489429EA1CB578 = {isa = PBXBuildFile; fileRef = 9A911A3FA0E325ABF55867A0; };
-               F0701F95186DA3A40A886DB6 = {isa = PBXBuildFile; fileRef = 04490001D298BA2346FF6189; };
-               006DB50986A0346D98807D97 = {isa = PBXBuildFile; fileRef = 955DDD461A5C3E9C22B7BE39; };
-               0830C88F5BCD8EAC20E32CD3 = {isa = PBXBuildFile; fileRef = 7F622DCB8702AC0625A6EE0F; };
-               E774DAD5CD373E9117FA1C6C = {isa = PBXBuildFile; fileRef = E43E01CF419E2B8F84208147; };
-               2DC1C2164642836F0AEA40A8 = {isa = PBXBuildFile; fileRef = 054C82A4C1AB1EBC06ED0C8B; };
-               756A7AB6373D013FF081857B = {isa = PBXBuildFile; fileRef = CB06C0F473344197E379229C; };
-               E93AB2D1FE2B626F8D206477 = {isa = PBXBuildFile; fileRef = 929C87E7E3C0BE332F95BD5E; };
-               17A4AA2C7BD1A5303EF23E4C = {isa = PBXBuildFile; fileRef = 9EB484DB75BF878F807AC137; };
-               73850D87E50FB5196EE6B422 = {isa = PBXBuildFile; fileRef = 4A6D87778399E33A46D3F8D1; };
-               272C981B90E5FCF85FC2B356 = {isa = PBXBuildFile; fileRef = 097E110FC89C469C60690346; };
-               61A2A777A5E2165A58CB7FA1 = {isa = PBXBuildFile; fileRef = 0F3DE7E51F0C8FA40039124C; };
-               3A6BADD63BD2CD4C2A4B8B92 = {isa = PBXBuildFile; fileRef = 26781A9A72E1FDBA098F3DF7; };
-               BF2FAB5969AC733B0329C975 = {isa = PBXBuildFile; fileRef = 9571B95A6DC17D950A3E7927; };
-               FF0E86794C1852BE55EF2DE7 = {isa = PBXBuildFile; fileRef = FA96318BFF18EF22CCD5D2C0; };
-               A22B5F90E70672CBEEDBE4D4 = {isa = PBXBuildFile; fileRef = 4087203F4F8298986FA095CF; };
-               608C0EEE88E50CEB33FD93B0 = {isa = PBXBuildFile; fileRef = CA3C94ECDD8ECB56C7CDAD40; };
-               3B41F9F3BA57A45FDD2CF687 = {isa = PBXBuildFile; fileRef = 14A62E059CCEFF286B2FDC5B; };
-               8A90259D6376541FCCDBF59C = {isa = PBXBuildFile; fileRef = 1A96A352C0EC9618525AF0B7; };
-               32E555692EA88756C8AE33C4 = {isa = PBXBuildFile; fileRef = C4ADFA88BEBEA08666061564; };
-               B6158CAAC9D313E28AC0DF0D = {isa = PBXBuildFile; fileRef = 3A947DDFC32557DF9382998A; };
-               1E614F5E3EC385511F4230C4 = {isa = PBXBuildFile; fileRef = 06245F7CFB768425900553E7; };
-               801983262C42D57DC51ACF6B = {isa = PBXBuildFile; fileRef = C4AE3AE69E8A836ED900280D; };
-               F664B60DDB169E8ACA354AF9 = {isa = PBXBuildFile; fileRef = 11CBB5471F59AAE6E49BEFD2; };
-               76D886AA6B0E90D452F10F02 = {isa = PBXBuildFile; fileRef = BF0A51F9471E4D76EF835FAA; };
-               F0CB20CC1945DAFF9E561761 = {isa = PBXBuildFile; fileRef = 13D7E942C9E011C021B85BF9; };
-               1E5DFED918A016879F0E4FB6 = {isa = PBXBuildFile; fileRef = 769FFD43EF73DCB4041FCA75; };
-               534602D32BB67E55866BFD6B = {isa = PBXBuildFile; fileRef = D627A26CC3A04157C5D514AF; };
-               B03DADDEC5B4385D509471E8 = {isa = PBXBuildFile; fileRef = A6C9AAF871AEACE8A7825F1E; };
-               3C5CC8F258D9631CBABF41F3 = {isa = PBXBuildFile; fileRef = D50F316F3E0B6A478EB59989; };
-               4AC737FF1A171EF7ED650753 = {isa = PBXBuildFile; fileRef = A85ADFA746A1D9678E00A168; };
-               FFD08F7DE6EE7278D22A4D8D = {isa = PBXBuildFile; fileRef = 3D0011FC57C8B5226D753F92; };
-               0326AFEA87C4FB4537983A3E = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
-               04490001D298BA2346FF6189 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
-               0481B3E625AB0C716608526E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_basics"; path = "../../../../modules/juce_audio_basics"; sourceTree = "SOURCE_ROOT"; };
-               04BD12AE0CE600640E3F489D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SettingsContent.h; path = ../../Source/UI/SettingsContent.h; sourceTree = "SOURCE_ROOT"; };
-               04F8192B4B8F84153D662FC2 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_osc"; path = "../../../../modules/juce_osc"; sourceTree = "SOURCE_ROOT"; };
-               054C82A4C1AB1EBC06ED0C8B = {isa = PBXFileReference; lastKnownFileType = file.icns; name = Icon.icns; path = Icon.icns; sourceTree = "SOURCE_ROOT"; };
-               06245F7CFB768425900553E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_cryptography.mm"; path = "../../JuceLibraryCode/include_juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; };
-               097E110FC89C469C60690346 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MainComponent.cpp; path = ../../Source/UI/MainComponent.cpp; sourceTree = "SOURCE_ROOT"; };
-               0F3DE7E51F0C8FA40039124C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Main.cpp; path = ../../Source/Main.cpp; sourceTree = "SOURCE_ROOT"; };
-               11CBB5471F59AAE6E49BEFD2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_dsp.mm"; path = "../../JuceLibraryCode/include_juce_dsp.mm"; sourceTree = "SOURCE_ROOT"; };
-               13D7E942C9E011C021B85BF9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_graphics.mm"; path = "../../JuceLibraryCode/include_juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; };
-               14A62E059CCEFF286B2FDC5B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_utils.mm"; path = "../../JuceLibraryCode/include_juce_audio_utils.mm"; sourceTree = "SOURCE_ROOT"; };
-               1575D9310DA31818620D1226 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-App.plist"; path = "Info-App.plist"; sourceTree = "SOURCE_ROOT"; };
-               18AAB3D924B310E3E279FC26 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_basics"; path = "../../../../modules/juce_gui_basics"; sourceTree = "SOURCE_ROOT"; };
-               1A96A352C0EC9618525AF0B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_blocks_basics.cpp"; path = "../../JuceLibraryCode/include_juce_blocks_basics.cpp"; sourceTree = "SOURCE_ROOT"; };
-               1FFDFDFBE666D3040758AF18 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
-               251035E70FD4DF8CB47CE11B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_extra"; path = "../../../../modules/juce_gui_extra"; sourceTree = "SOURCE_ROOT"; };
-               26781A9A72E1FDBA098F3DF7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_analytics.cpp"; path = "../../JuceLibraryCode/include_juce_analytics.cpp"; sourceTree = "SOURCE_ROOT"; };
-               26B6BE6368825BDC47A25EF0 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_cryptography"; path = "../../../../modules/juce_cryptography"; sourceTree = "SOURCE_ROOT"; };
-               27F6CB9E660948401CD97669 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; };
-               29ABFAEC066C2D76532D8536 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
-               2ED744F17B2133AC2EFEE9F9 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoRunner.app; sourceTree = "BUILT_PRODUCTS_DIR"; };
-               3A947DDFC32557DF9382998A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_core.mm"; path = "../../JuceLibraryCode/include_juce_core.mm"; sourceTree = "SOURCE_ROOT"; };
-               3D0011FC57C8B5226D753F92 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_video.mm"; path = "../../JuceLibraryCode/include_juce_video.mm"; sourceTree = "SOURCE_ROOT"; };
-               4087203F4F8298986FA095CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_formats.mm"; path = "../../JuceLibraryCode/include_juce_audio_formats.mm"; sourceTree = "SOURCE_ROOT"; };
-               4124591B632A530112C2F1D6 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioKit.framework; path = System/Library/Frameworks/CoreAudioKit.framework; sourceTree = SDKROOT; };
-               4635F50C3A84562B3846D885 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_devices"; path = "../../../../modules/juce_audio_devices"; sourceTree = "SOURCE_ROOT"; };
-               472E123B48C4A21B4A4BC38A = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = DemoRunner.entitlements; path = DemoRunner.entitlements; sourceTree = "SOURCE_ROOT"; };
-               4A6D87778399E33A46D3F8D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DemoContentComponent.cpp; path = ../../Source/UI/DemoContentComponent.cpp; sourceTree = "SOURCE_ROOT"; };
-               4E8B6E7BD608C8BAB3D34E5E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_utils"; path = "../../../../modules/juce_audio_utils"; sourceTree = "SOURCE_ROOT"; };
-               5043B6C9ED9A1A340C7F13EF = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_formats"; path = "../../../../modules/juce_audio_formats"; sourceTree = "SOURCE_ROOT"; };
-               563422D82232DCEF5C4750FB = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_analytics"; path = "../../../../modules/juce_analytics"; sourceTree = "SOURCE_ROOT"; };
-               5E2942A56F119F3C7A68EC27 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_box2d"; path = "../../../../modules/juce_box2d"; sourceTree = "SOURCE_ROOT"; };
-               5E797E3AE76E4638F96F57ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JUCEDemos.h; path = ../../Source/Demos/JUCEDemos.h; sourceTree = "SOURCE_ROOT"; };
-               63E6F3607FC65720942EC5EF = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_product_unlocking"; path = "../../../../modules/juce_product_unlocking"; sourceTree = "SOURCE_ROOT"; };
-               64F96A9995CAA940ECA9CE79 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_video"; path = "../../../../modules/juce_video"; sourceTree = "SOURCE_ROOT"; };
-               655CE61850C4C0BAF8E09DF6 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
-               66B6C67613E5B479E528AEA9 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_data_structures"; path = "../../../../modules/juce_data_structures"; sourceTree = "SOURCE_ROOT"; };
-               6A979C969585431AD3FC1DE7 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
-               6E16E438CD7F913C4FCC466C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; };
-               769FFD43EF73DCB4041FCA75 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_basics.mm"; path = "../../JuceLibraryCode/include_juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; };
-               779385E9110DED1036B6DD87 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_processors"; path = "../../../../modules/juce_audio_processors"; sourceTree = "SOURCE_ROOT"; };
-               7A4EF0463F65419994870CF8 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_opengl"; path = "../../../../modules/juce_opengl"; sourceTree = "SOURCE_ROOT"; };
-               7D342958D0DBE535A3D275A0 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
-               7D3B7614BDF9DFBD3204A98B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_dsp"; path = "../../../../modules/juce_dsp"; sourceTree = "SOURCE_ROOT"; };
-               7F622DCB8702AC0625A6EE0F = {isa = PBXFileReference; lastKnownFileType = folder; name = Assets; path = ../../../Assets; sourceTree = "<group>"; };
-               86136E61D36EA0371D61DA88 = {isa = PBXFileReference; lastKnownFileType = image.png; name = JUCEAppIcon.png; path = ../../Source/JUCEAppIcon.png; sourceTree = "SOURCE_ROOT"; };
-               8CE0B384BE015EB8B43E0B8A = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
-               8DD853F21171698ECF027383 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DemoContentComponent.h; path = ../../Source/UI/DemoContentComponent.h; sourceTree = "SOURCE_ROOT"; };
-               929C87E7E3C0BE332F95BD5E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DemoPIPs2.cpp; path = ../../Source/Demos/DemoPIPs2.cpp; sourceTree = "SOURCE_ROOT"; };
-               955DDD461A5C3E9C22B7BE39 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
-               9571B95A6DC17D950A3E7927 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_basics.mm"; path = "../../JuceLibraryCode/include_juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; };
-               9A911A3FA0E325ABF55867A0 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
-               9EB484DB75BF878F807AC137 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = JUCEDemos.cpp; path = ../../Source/Demos/JUCEDemos.cpp; sourceTree = "SOURCE_ROOT"; };
-               9F3EC9807829FC79CB8CD957 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_blocks_basics"; path = "../../../../modules/juce_blocks_basics"; sourceTree = "SOURCE_ROOT"; };
-               A2B31FC014B1F1A8B4EBE44B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_events"; path = "../../../../modules/juce_events"; sourceTree = "SOURCE_ROOT"; };
-               A6C9AAF871AEACE8A7825F1E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_opengl.mm"; path = "../../JuceLibraryCode/include_juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; };
-               A85ADFA746A1D9678E00A168 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_product_unlocking.mm"; path = "../../JuceLibraryCode/include_juce_product_unlocking.mm"; sourceTree = "SOURCE_ROOT"; };
-               B2AFD70A87FA31DC08B38DA7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; };
-               B40D157D83FA7723FC469D74 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_core"; path = "../../../../modules/juce_core"; sourceTree = "SOURCE_ROOT"; };
-               B750A664A1E944AD116626FE = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; };
-               BF0A51F9471E4D76EF835FAA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_events.mm"; path = "../../JuceLibraryCode/include_juce_events.mm"; sourceTree = "SOURCE_ROOT"; };
-               BFFD2BA0FA2CD7A91A4A8F60 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IntroScreen.h; path = ../../Source/Demos/IntroScreen.h; sourceTree = "SOURCE_ROOT"; };
-               C4ADFA88BEBEA08666061564 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_box2d.cpp"; path = "../../JuceLibraryCode/include_juce_box2d.cpp"; sourceTree = "SOURCE_ROOT"; };
-               C4AE3AE69E8A836ED900280D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_data_structures.mm"; path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
-               CA3C94ECDD8ECB56C7CDAD40 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_processors.mm"; path = "../../JuceLibraryCode/include_juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; };
-               CB06C0F473344197E379229C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DemoPIPs1.cpp; path = ../../Source/Demos/DemoPIPs1.cpp; sourceTree = "SOURCE_ROOT"; };
-               D50F316F3E0B6A478EB59989 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_osc.cpp"; path = "../../JuceLibraryCode/include_juce_osc.cpp"; sourceTree = "SOURCE_ROOT"; };
-               D627A26CC3A04157C5D514AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_extra.mm"; path = "../../JuceLibraryCode/include_juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; };
-               DC46EC2AEC1139B659B5DF05 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
-               E43E01CF419E2B8F84208147 = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = DemoRunner/Images.xcassets; sourceTree = "SOURCE_ROOT"; };
-               E95BB1D476BE36D1A6AD7F7E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_graphics"; path = "../../../../modules/juce_graphics"; sourceTree = "SOURCE_ROOT"; };
-               E9BDE77C1EB97BBEE49D013A = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
-               ECE30C4CD43873204B4B9E32 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
-               FA96318BFF18EF22CCD5D2C0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_devices.mm"; path = "../../JuceLibraryCode/include_juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; };
-               FC235E64CF9B125F89DEE9A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MainComponent.h; path = ../../Source/UI/MainComponent.h; sourceTree = "SOURCE_ROOT"; };
-               4E55327B63E34F22FA7D6C10 = {isa = PBXGroup; children = (
-                                       CB06C0F473344197E379229C,
-                                       929C87E7E3C0BE332F95BD5E,
-                                       BFFD2BA0FA2CD7A91A4A8F60,
-                                       9EB484DB75BF878F807AC137,
-                                       5E797E3AE76E4638F96F57ED, ); name = Demos; sourceTree = "<group>"; };
-               BAB989491CF1D9747AEC0688 = {isa = PBXGroup; children = (
-                                       4A6D87778399E33A46D3F8D1,
-                                       8DD853F21171698ECF027383,
-                                       097E110FC89C469C60690346,
-                                       FC235E64CF9B125F89DEE9A3,
-                                       04BD12AE0CE600640E3F489D, ); name = UI; sourceTree = "<group>"; };
-               7F8CAA66A1D07FBC72E0F95F = {isa = PBXGroup; children = (
-                                       4E55327B63E34F22FA7D6C10,
-                                       BAB989491CF1D9747AEC0688,
-                                       0F3DE7E51F0C8FA40039124C,
-                                       86136E61D36EA0371D61DA88, ); name = Source; sourceTree = "<group>"; };
-               8A320092FEC850844C33A1D6 = {isa = PBXGroup; children = (
-                                       7F8CAA66A1D07FBC72E0F95F, ); name = DemoRunner; sourceTree = "<group>"; };
-               353089C68F5C428ECD9E60A4 = {isa = PBXGroup; children = (
-                                       563422D82232DCEF5C4750FB,
-                                       0481B3E625AB0C716608526E,
-                                       4635F50C3A84562B3846D885,
-                                       5043B6C9ED9A1A340C7F13EF,
-                                       779385E9110DED1036B6DD87,
-                                       4E8B6E7BD608C8BAB3D34E5E,
-                                       9F3EC9807829FC79CB8CD957,
-                                       5E2942A56F119F3C7A68EC27,
-                                       B40D157D83FA7723FC469D74,
-                                       26B6BE6368825BDC47A25EF0,
-                                       66B6C67613E5B479E528AEA9,
-                                       7D3B7614BDF9DFBD3204A98B,
-                                       A2B31FC014B1F1A8B4EBE44B,
-                                       E95BB1D476BE36D1A6AD7F7E,
-                                       18AAB3D924B310E3E279FC26,
-                                       251035E70FD4DF8CB47CE11B,
-                                       7A4EF0463F65419994870CF8,
-                                       04F8192B4B8F84153D662FC2,
-                                       63E6F3607FC65720942EC5EF,
-                                       64F96A9995CAA940ECA9CE79, ); name = "JUCE Modules"; sourceTree = "<group>"; };
-               65D8429D8521FB2026D340E3 = {isa = PBXGroup; children = (
-                                       B2AFD70A87FA31DC08B38DA7,
-                                       26781A9A72E1FDBA098F3DF7,
-                                       9571B95A6DC17D950A3E7927,
-                                       FA96318BFF18EF22CCD5D2C0,
-                                       4087203F4F8298986FA095CF,
-                                       CA3C94ECDD8ECB56C7CDAD40,
-                                       14A62E059CCEFF286B2FDC5B,
-                                       1A96A352C0EC9618525AF0B7,
-                                       C4ADFA88BEBEA08666061564,
-                                       3A947DDFC32557DF9382998A,
-                                       06245F7CFB768425900553E7,
-                                       C4AE3AE69E8A836ED900280D,
-                                       11CBB5471F59AAE6E49BEFD2,
-                                       BF0A51F9471E4D76EF835FAA,
-                                       13D7E942C9E011C021B85BF9,
-                                       769FFD43EF73DCB4041FCA75,
-                                       D627A26CC3A04157C5D514AF,
-                                       A6C9AAF871AEACE8A7825F1E,
-                                       D50F316F3E0B6A478EB59989,
-                                       A85ADFA746A1D9678E00A168,
-                                       3D0011FC57C8B5226D753F92,
-                                       6E16E438CD7F913C4FCC466C, ); name = "JUCE Library Code"; sourceTree = "<group>"; };
-               D2567B3F9EE06A8DB02822E1 = {isa = PBXGroup; children = (
-                                       7F622DCB8702AC0625A6EE0F,
-                                       1575D9310DA31818620D1226,
-                                       E43E01CF419E2B8F84208147,
-                                       054C82A4C1AB1EBC06ED0C8B, ); name = Resources; sourceTree = "<group>"; };
-               472A17EE8274BF9716190070 = {isa = PBXGroup; children = (
-                                       ECE30C4CD43873204B4B9E32,
-                                       0326AFEA87C4FB4537983A3E,
-                                       8CE0B384BE015EB8B43E0B8A,
-                                       27F6CB9E660948401CD97669,
-                                       1FFDFDFBE666D3040758AF18,
-                                       4124591B632A530112C2F1D6,
-                                       655CE61850C4C0BAF8E09DF6,
-                                       B750A664A1E944AD116626FE,
-                                       29ABFAEC066C2D76532D8536,
-                                       6A979C969585431AD3FC1DE7,
-                                       E9BDE77C1EB97BBEE49D013A,
-                                       DC46EC2AEC1139B659B5DF05,
-                                       7D342958D0DBE535A3D275A0,
-                                       9A911A3FA0E325ABF55867A0,
-                                       04490001D298BA2346FF6189,
-                                       955DDD461A5C3E9C22B7BE39, ); name = Frameworks; sourceTree = "<group>"; };
-               53B1E8BA690225D0DCC7118A = {isa = PBXGroup; children = (
-                                       2ED744F17B2133AC2EFEE9F9, ); name = Products; sourceTree = "<group>"; };
-               12C3AAFF06FB271063BD3774 = {isa = PBXGroup; children = (
-                                       472E123B48C4A21B4A4BC38A,
-                                       8A320092FEC850844C33A1D6,
-                                       353089C68F5C428ECD9E60A4,
-                                       65D8429D8521FB2026D340E3,
-                                       D2567B3F9EE06A8DB02822E1,
-                                       472A17EE8274BF9716190070,
-                                       53B1E8BA690225D0DCC7118A, ); name = Source; sourceTree = "<group>"; };
-               0BF6FF13ABD310AA426C4D86 = {isa = XCBuildConfiguration; buildSettings = {
+               5665A011C7D125C8890D3260 = {isa = PBXBuildFile; fileRef = B953F5C249804F38B818AD2F; };
+               C8D093204643DE75CAA41A3F = {isa = PBXBuildFile; fileRef = E622C086CB768052D799CB95; };
+               7286A5BB489F25E6E3CF63D4 = {isa = PBXBuildFile; fileRef = A70E204AA2B7B904F9C08770; };
+               B6AB4CB9F0A0AD540028A3E1 = {isa = PBXBuildFile; fileRef = F10017EB39A3981DF2FFC565; };
+               71F90E5ABB1112D2D92EAB59 = {isa = PBXBuildFile; fileRef = 61BF1C5B6EB2C49337A028E7; };
+               AB53895F1E4193A2C9B51DB6 = {isa = PBXBuildFile; fileRef = 5AB31D4FDB61420CFE50FD52; };
+               9CB6071FE1DD378F7C64C9F5 = {isa = PBXBuildFile; fileRef = 4400AFF27C798108026C3094; };
+               1D98F6C4127BB7F0890645D6 = {isa = PBXBuildFile; fileRef = C0349D711DBA26CB337AFDFC; };
+               0B1AC7FEC205238C5701B086 = {isa = PBXBuildFile; fileRef = E087A95F121B72288CFE0150; };
+               2EF15A7E6ECFD861D719276A = {isa = PBXBuildFile; fileRef = BE800C80B08E6D722CACB487; };
+               9318D1152DE35146100C7594 = {isa = PBXBuildFile; fileRef = 95C3EC76835BB2151FA94A67; };
+               BA3F994E8752E7310789C02A = {isa = PBXBuildFile; fileRef = 0CD10A62A53B1C25DBFC9ECB; };
+               06DA6875AC3E734378E374C5 = {isa = PBXBuildFile; fileRef = 0F072771BD806EFDDADEBF26; };
+               9F59844F463603E7C2467DC4 = {isa = PBXBuildFile; fileRef = 0C3170AEED96E4A60DD8E49F; };
+               C7D4E452620DF858B785BA82 = {isa = PBXBuildFile; fileRef = F4929902D6A38E01A6B084E8; };
+               3D2D1CCFB4B682162034225E = {isa = PBXBuildFile; fileRef = 6142F838E6568F8450BC93DB; };
+               EDAD741A46FD4B3F002C96D3 = {isa = PBXBuildFile; fileRef = 58E1DD950580FC057346CF2F; };
+               B1776D2FEB204FAE5C17E4C7 = {isa = PBXBuildFile; fileRef = A5C76AB7D5C174FB79974A8B; };
+               686146610021944DA9C987B8 = {isa = PBXBuildFile; fileRef = AC925129DC8F53C3C3F6E0BF; };
+               F657E50CA75FE6932E710CB0 = {isa = PBXBuildFile; fileRef = 2945A953347C882A8294DF82; };
+               F9EDB3A8F55A4499441401D6 = {isa = PBXBuildFile; fileRef = AE5650194191C6A04F0B5685; };
+               EACB962CC04BDC0369264A8F = {isa = PBXBuildFile; fileRef = 48A8B50CEB577DF7D3FCEFEC; };
+               557BA8FDD37630DF5EB84EE0 = {isa = PBXBuildFile; fileRef = 5FE974D1CE11D7658D57C580; };
+               5CFCACD6AF608BDC2E1E8BD1 = {isa = PBXBuildFile; fileRef = E40C7EC0CD57D5F92EC9C806; };
+               9263171BCE90616A9F350405 = {isa = PBXBuildFile; fileRef = 56280EAEBEAF619C3E98B5C6; };
+               2EF49BC29DA0951B1C43070F = {isa = PBXBuildFile; fileRef = 27FB5D78BF900B70101B3E48; };
+               8861132DCB0DE3F9EB0DD278 = {isa = PBXBuildFile; fileRef = BD545E9E8BA9D67A673AC8E8; };
+               CCDAEA12C17058099252FD3D = {isa = PBXBuildFile; fileRef = 44B4D9F7DBB239B6E57BC2E7; };
+               28778136A8C09DBDC980CB72 = {isa = PBXBuildFile; fileRef = 2CC2281747C1FE9EB940BD1A; };
+               DA696766645C964870153095 = {isa = PBXBuildFile; fileRef = F996277A397F3F21763BAC03; };
+               8F5FE1B5D44F55667509BC99 = {isa = PBXBuildFile; fileRef = 91195E76A94C136774686D97; };
+               3656169644FED0C525D5D30C = {isa = PBXBuildFile; fileRef = 3290EFAFF391EE790FF33FB9; };
+               2763512B6DFF68C0EEF72496 = {isa = PBXBuildFile; fileRef = 46A8BE3E064F7E01EF1E2D2D; };
+               480F45A17B4E83A26B1ACEF9 = {isa = PBXBuildFile; fileRef = 1442C6A9928B564A86D1597A; };
+               3D8EECDED13F0A46A6FA8D3E = {isa = PBXBuildFile; fileRef = 9A35450231D4C3F4DCF16AB3; };
+               E433C1C591D091AF71AD528E = {isa = PBXBuildFile; fileRef = 55479FCC6DB5293B12918CBA; };
+               A5F8F9904580960794429360 = {isa = PBXBuildFile; fileRef = 9733178D30027A7CC3E12510; };
+               B298295E61E5DD800B814DAF = {isa = PBXBuildFile; fileRef = 7445067DFFF67F28456DA9B0; };
+               A7E206DD280DC58E2A150642 = {isa = PBXBuildFile; fileRef = 1EF8C1691168417E42DF81ED; };
+               26260D259EFF13BD5044CD34 = {isa = PBXBuildFile; fileRef = 120B5B68C50C2992969E9CE1; };
+               591D5799ED6524DE9BD846D7 = {isa = PBXBuildFile; fileRef = 0996038E1E70A6ADD233418D; };
+               D09859BDBC491A9932637715 = {isa = PBXBuildFile; fileRef = 96FE3B2079CA29C6C2F5E2F2; };
+               7EC8A06F9290B16DFB16E346 = {isa = PBXBuildFile; fileRef = A477616D8A134C6E99C2BE9D; };
+               33C96917E46535D30B17B483 = {isa = PBXBuildFile; fileRef = 5F79F2C9508D0D7F5A6BF62D; };
+               8AA7BB967216BDBFF0371267 = {isa = PBXBuildFile; fileRef = 6B2332953FCDD3BD197E149A; };
+               FD5B59B8A0B8258531421E60 = {isa = PBXBuildFile; fileRef = F4AB4BBB26E536232D27BE83; };
+               0996038E1E70A6ADD233418D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_basics.mm"; path = "../../JuceLibraryCode/include_juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; };
+               09AFF79B4D5593574507F03E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_utils"; path = "../../../../modules/juce_audio_utils"; sourceTree = "SOURCE_ROOT"; };
+               0C3170AEED96E4A60DD8E49F = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
+               0CD10A62A53B1C25DBFC9ECB = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
+               0D328B4591EBFD9997C61535 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_product_unlocking"; path = "../../../../modules/juce_product_unlocking"; sourceTree = "SOURCE_ROOT"; };
+               0F072771BD806EFDDADEBF26 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+               120B5B68C50C2992969E9CE1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_graphics.mm"; path = "../../JuceLibraryCode/include_juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; };
+               1442C6A9928B564A86D1597A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_box2d.cpp"; path = "../../JuceLibraryCode/include_juce_box2d.cpp"; sourceTree = "SOURCE_ROOT"; };
+               18C1EBA9CB73E8E7389BBDCC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; };
+               191B33D36B749639B0FBE856 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MainComponent.h; path = ../../Source/UI/MainComponent.h; sourceTree = "SOURCE_ROOT"; };
+               1EF8C1691168417E42DF81ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_events.mm"; path = "../../JuceLibraryCode/include_juce_events.mm"; sourceTree = "SOURCE_ROOT"; };
+               27FB5D78BF900B70101B3E48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Main.cpp; path = ../../Source/Main.cpp; sourceTree = "SOURCE_ROOT"; };
+               2945A953347C882A8294DF82 = {isa = PBXFileReference; lastKnownFileType = file.icns; name = Icon.icns; path = Icon.icns; sourceTree = "SOURCE_ROOT"; };
+               2CC2281747C1FE9EB940BD1A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_devices.mm"; path = "../../JuceLibraryCode/include_juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; };
+               3290EFAFF391EE790FF33FB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_utils.mm"; path = "../../JuceLibraryCode/include_juce_audio_utils.mm"; sourceTree = "SOURCE_ROOT"; };
+               3384C796C682AF43B57B42F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JUCEDemos.h; path = ../../Source/Demos/JUCEDemos.h; sourceTree = "SOURCE_ROOT"; };
+               352AF685E88FF055C4F20E16 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = DemoRunner.entitlements; path = DemoRunner.entitlements; sourceTree = "SOURCE_ROOT"; };
+               4400AFF27C798108026C3094 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioKit.framework; path = System/Library/Frameworks/CoreAudioKit.framework; sourceTree = SDKROOT; };
+               44B4D9F7DBB239B6E57BC2E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_basics.mm"; path = "../../JuceLibraryCode/include_juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; };
+               46A8BE3E064F7E01EF1E2D2D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_blocks_basics.cpp"; path = "../../JuceLibraryCode/include_juce_blocks_basics.cpp"; sourceTree = "SOURCE_ROOT"; };
+               47623ED30F98E053C07A9B11 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_dsp"; path = "../../../../modules/juce_dsp"; sourceTree = "SOURCE_ROOT"; };
+               483FAD2B91F1B2A248684D8D = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_graphics"; path = "../../../../modules/juce_graphics"; sourceTree = "SOURCE_ROOT"; };
+               48A8B50CEB577DF7D3FCEFEC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DemoPIPs2.cpp; path = ../../Source/Demos/DemoPIPs2.cpp; sourceTree = "SOURCE_ROOT"; };
+               497F44004821C9FDC0B1A337 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DemoContentComponent.h; path = ../../Source/UI/DemoContentComponent.h; sourceTree = "SOURCE_ROOT"; };
+               4B2E65945C61CDD81D945CC3 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_analytics"; path = "../../../../modules/juce_analytics"; sourceTree = "SOURCE_ROOT"; };
+               531F8760E51457787457AC3D = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_opengl"; path = "../../../../modules/juce_opengl"; sourceTree = "SOURCE_ROOT"; };
+               53ED8C56ECA0B933135E6ED5 = {isa = PBXFileReference; lastKnownFileType = image.png; name = JUCEAppIcon.png; path = ../../Source/JUCEAppIcon.png; sourceTree = "SOURCE_ROOT"; };
+               55479FCC6DB5293B12918CBA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_cryptography.mm"; path = "../../JuceLibraryCode/include_juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; };
+               56280EAEBEAF619C3E98B5C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MainComponent.cpp; path = ../../Source/UI/MainComponent.cpp; sourceTree = "SOURCE_ROOT"; };
+               58E1DD950580FC057346CF2F = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+               5AB31D4FDB61420CFE50FD52 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
+               5F79F2C9508D0D7F5A6BF62D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_osc.cpp"; path = "../../JuceLibraryCode/include_juce_osc.cpp"; sourceTree = "SOURCE_ROOT"; };
+               5FE974D1CE11D7658D57C580 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = JUCEDemos.cpp; path = ../../Source/Demos/JUCEDemos.cpp; sourceTree = "SOURCE_ROOT"; };
+               6142F838E6568F8450BC93DB = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+               61BF1C5B6EB2C49337A028E7 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; };
+               62B6BD963ACD31048A939441 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_devices"; path = "../../../../modules/juce_audio_devices"; sourceTree = "SOURCE_ROOT"; };
+               6B2332953FCDD3BD197E149A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_product_unlocking.mm"; path = "../../JuceLibraryCode/include_juce_product_unlocking.mm"; sourceTree = "SOURCE_ROOT"; };
+               7445067DFFF67F28456DA9B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_dsp.mm"; path = "../../JuceLibraryCode/include_juce_dsp.mm"; sourceTree = "SOURCE_ROOT"; };
+               74E8AB27C5B4246DA0590820 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IntroScreen.h; path = ../../Source/Demos/IntroScreen.h; sourceTree = "SOURCE_ROOT"; };
+               8DA81A2479F1EF4B1064E3A0 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-App.plist"; path = "Info-App.plist"; sourceTree = "SOURCE_ROOT"; };
+               91195E76A94C136774686D97 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_processors.mm"; path = "../../JuceLibraryCode/include_juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; };
+               95C3EC76835BB2151FA94A67 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
+               96FE3B2079CA29C6C2F5E2F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_extra.mm"; path = "../../JuceLibraryCode/include_juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; };
+               9733178D30027A7CC3E12510 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_data_structures.mm"; path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
+               9A35450231D4C3F4DCF16AB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_core.mm"; path = "../../JuceLibraryCode/include_juce_core.mm"; sourceTree = "SOURCE_ROOT"; };
+               9A974BD82436ED647B457D0B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_data_structures"; path = "../../../../modules/juce_data_structures"; sourceTree = "SOURCE_ROOT"; };
+               9AA6843063F8D624808AA5FF = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_blocks_basics"; path = "../../../../modules/juce_blocks_basics"; sourceTree = "SOURCE_ROOT"; };
+               9D3C18C7CD24710A9D88CACB = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_osc"; path = "../../../../modules/juce_osc"; sourceTree = "SOURCE_ROOT"; };
+               A075E4A80B931C9431786CB4 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_formats"; path = "../../../../modules/juce_audio_formats"; sourceTree = "SOURCE_ROOT"; };
+               A477616D8A134C6E99C2BE9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_opengl.mm"; path = "../../JuceLibraryCode/include_juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; };
+               A5C76AB7D5C174FB79974A8B = {isa = PBXFileReference; lastKnownFileType = folder; name = Assets; path = ../../../Assets; sourceTree = "<group>"; };
+               A70E204AA2B7B904F9C08770 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
+               AC925129DC8F53C3C3F6E0BF = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = DemoRunner/Images.xcassets; sourceTree = "SOURCE_ROOT"; };
+               AE309D5EC9B20A17B819B264 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_processors"; path = "../../../../modules/juce_audio_processors"; sourceTree = "SOURCE_ROOT"; };
+               AE5650194191C6A04F0B5685 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DemoPIPs1.cpp; path = ../../Source/Demos/DemoPIPs1.cpp; sourceTree = "SOURCE_ROOT"; };
+               AE80AC9B628F8B74C6F1F29E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_events"; path = "../../../../modules/juce_events"; sourceTree = "SOURCE_ROOT"; };
+               B953F5C249804F38B818AD2F = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoRunner.app; sourceTree = "BUILT_PRODUCTS_DIR"; };
+               BD545E9E8BA9D67A673AC8E8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_analytics.cpp"; path = "../../JuceLibraryCode/include_juce_analytics.cpp"; sourceTree = "SOURCE_ROOT"; };
+               BE800C80B08E6D722CACB487 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
+               BF3AA167B271DBCB79CE3510 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_basics"; path = "../../../../modules/juce_audio_basics"; sourceTree = "SOURCE_ROOT"; };
+               C0349D711DBA26CB337AFDFC = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+               D869E1D6485900AB3406AF03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SettingsContent.h; path = ../../Source/UI/SettingsContent.h; sourceTree = "SOURCE_ROOT"; };
+               D93CFD2601C0E84D357B7959 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_core"; path = "../../../../modules/juce_core"; sourceTree = "SOURCE_ROOT"; };
+               E087A95F121B72288CFE0150 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; };
+               E40C7EC0CD57D5F92EC9C806 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DemoContentComponent.cpp; path = ../../Source/UI/DemoContentComponent.cpp; sourceTree = "SOURCE_ROOT"; };
+               E4A1F27BDB0FEAB8FD971583 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_box2d"; path = "../../../../modules/juce_box2d"; sourceTree = "SOURCE_ROOT"; };
+               E5CF2486265244CD996876FE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; };
+               E622C086CB768052D799CB95 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
+               ECFF9E66EC18BEAEF2B6C686 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_video"; path = "../../../../modules/juce_video"; sourceTree = "SOURCE_ROOT"; };
+               F10017EB39A3981DF2FFC565 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
+               F124B2F09BEA556820420758 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_basics"; path = "../../../../modules/juce_gui_basics"; sourceTree = "SOURCE_ROOT"; };
+               F3C0C37FD6A1BBBB6588D182 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_extra"; path = "../../../../modules/juce_gui_extra"; sourceTree = "SOURCE_ROOT"; };
+               F4929902D6A38E01A6B084E8 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
+               F4AB4BBB26E536232D27BE83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_video.mm"; path = "../../JuceLibraryCode/include_juce_video.mm"; sourceTree = "SOURCE_ROOT"; };
+               F6E40DCC3B84C97202B9CC21 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_cryptography"; path = "../../../../modules/juce_cryptography"; sourceTree = "SOURCE_ROOT"; };
+               F996277A397F3F21763BAC03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_formats.mm"; path = "../../JuceLibraryCode/include_juce_audio_formats.mm"; sourceTree = "SOURCE_ROOT"; };
+               5F0F17E75142C9F8EC4F9EA8 = {isa = PBXGroup; children = (
+                                       AE5650194191C6A04F0B5685,
+                                       48A8B50CEB577DF7D3FCEFEC,
+                                       74E8AB27C5B4246DA0590820,
+                                       5FE974D1CE11D7658D57C580,
+                                       3384C796C682AF43B57B42F2, ); name = Demos; sourceTree = "<group>"; };
+               C69C98BDBD8901865A10D03D = {isa = PBXGroup; children = (
+                                       E40C7EC0CD57D5F92EC9C806,
+                                       497F44004821C9FDC0B1A337,
+                                       56280EAEBEAF619C3E98B5C6,
+                                       191B33D36B749639B0FBE856,
+                                       D869E1D6485900AB3406AF03, ); name = UI; sourceTree = "<group>"; };
+               29499B4E21D547DC19E2AF25 = {isa = PBXGroup; children = (
+                                       5F0F17E75142C9F8EC4F9EA8,
+                                       C69C98BDBD8901865A10D03D,
+                                       27FB5D78BF900B70101B3E48,
+                                       53ED8C56ECA0B933135E6ED5, ); name = Source; sourceTree = "<group>"; };
+               927472CBD503E38DD7E37090 = {isa = PBXGroup; children = (
+                                       29499B4E21D547DC19E2AF25, ); name = DemoRunner; sourceTree = "<group>"; };
+               178FF737E5519A4D16208DEB = {isa = PBXGroup; children = (
+                                       4B2E65945C61CDD81D945CC3,
+                                       BF3AA167B271DBCB79CE3510,
+                                       62B6BD963ACD31048A939441,
+                                       A075E4A80B931C9431786CB4,
+                                       AE309D5EC9B20A17B819B264,
+                                       09AFF79B4D5593574507F03E,
+                                       9AA6843063F8D624808AA5FF,
+                                       E4A1F27BDB0FEAB8FD971583,
+                                       D93CFD2601C0E84D357B7959,
+                                       F6E40DCC3B84C97202B9CC21,
+                                       9A974BD82436ED647B457D0B,
+                                       47623ED30F98E053C07A9B11,
+                                       AE80AC9B628F8B74C6F1F29E,
+                                       483FAD2B91F1B2A248684D8D,
+                                       F124B2F09BEA556820420758,
+                                       F3C0C37FD6A1BBBB6588D182,
+                                       531F8760E51457787457AC3D,
+                                       9D3C18C7CD24710A9D88CACB,
+                                       0D328B4591EBFD9997C61535,
+                                       ECFF9E66EC18BEAEF2B6C686, ); name = "JUCE Modules"; sourceTree = "<group>"; };
+               16DD35D8533EE0BA94AAFBF8 = {isa = PBXGroup; children = (
+                                       18C1EBA9CB73E8E7389BBDCC,
+                                       BD545E9E8BA9D67A673AC8E8,
+                                       44B4D9F7DBB239B6E57BC2E7,
+                                       2CC2281747C1FE9EB940BD1A,
+                                       F996277A397F3F21763BAC03,
+                                       91195E76A94C136774686D97,
+                                       3290EFAFF391EE790FF33FB9,
+                                       46A8BE3E064F7E01EF1E2D2D,
+                                       1442C6A9928B564A86D1597A,
+                                       9A35450231D4C3F4DCF16AB3,
+                                       55479FCC6DB5293B12918CBA,
+                                       9733178D30027A7CC3E12510,
+                                       7445067DFFF67F28456DA9B0,
+                                       1EF8C1691168417E42DF81ED,
+                                       120B5B68C50C2992969E9CE1,
+                                       0996038E1E70A6ADD233418D,
+                                       96FE3B2079CA29C6C2F5E2F2,
+                                       A477616D8A134C6E99C2BE9D,
+                                       5F79F2C9508D0D7F5A6BF62D,
+                                       6B2332953FCDD3BD197E149A,
+                                       F4AB4BBB26E536232D27BE83,
+                                       E5CF2486265244CD996876FE, ); name = "JUCE Library Code"; sourceTree = "<group>"; };
+               FEE1C6574320FAB66F0238D2 = {isa = PBXGroup; children = (
+                                       A5C76AB7D5C174FB79974A8B,
+                                       8DA81A2479F1EF4B1064E3A0,
+                                       AC925129DC8F53C3C3F6E0BF,
+                                       2945A953347C882A8294DF82, ); name = Resources; sourceTree = "<group>"; };
+               17F11FE561BD8D6EB93B64D4 = {isa = PBXGroup; children = (
+                                       E622C086CB768052D799CB95,
+                                       A70E204AA2B7B904F9C08770,
+                                       F10017EB39A3981DF2FFC565,
+                                       61BF1C5B6EB2C49337A028E7,
+                                       5AB31D4FDB61420CFE50FD52,
+                                       4400AFF27C798108026C3094,
+                                       C0349D711DBA26CB337AFDFC,
+                                       E087A95F121B72288CFE0150,
+                                       BE800C80B08E6D722CACB487,
+                                       95C3EC76835BB2151FA94A67,
+                                       0CD10A62A53B1C25DBFC9ECB,
+                                       0F072771BD806EFDDADEBF26,
+                                       0C3170AEED96E4A60DD8E49F,
+                                       F4929902D6A38E01A6B084E8,
+                                       6142F838E6568F8450BC93DB,
+                                       58E1DD950580FC057346CF2F, ); name = Frameworks; sourceTree = "<group>"; };
+               532CECDAA91A39864E7FFF80 = {isa = PBXGroup; children = (
+                                       B953F5C249804F38B818AD2F, ); name = Products; sourceTree = "<group>"; };
+               9979C8B054ED17C9E04C6BAB = {isa = PBXGroup; children = (
+                                       352AF685E88FF055C4F20E16,
+                                       927472CBD503E38DD7E37090,
+                                       178FF737E5519A4D16208DEB,
+                                       16DD35D8533EE0BA94AAFBF8,
+                                       FEE1C6574320FAB66F0238D2,
+                                       17F11FE561BD8D6EB93B64D4,
+                                       532CECDAA91A39864E7FFF80, ); name = Source; sourceTree = "<group>"; };
+               CEC200AA273D1626F466FC27 = {isa = XCBuildConfiguration; buildSettings = {
                                ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
                                ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
                                CLANG_CXX_LANGUAGE_STANDARD = "c++14";
                                        "JUCE_DEMO_RUNNER=1",
                                        "JUCE_UNIT_TESTS=1",
                                        "JUCER_XCODE_IPHONE_5BC26AE3=1",
-                                       "JUCE_APP_VERSION=5.2.1",
-                                       "JUCE_APP_VERSION_HEX=0x50201",
+                                       "JUCE_APP_VERSION=5.3.1",
+                                       "JUCE_APP_VERSION_HEX=0x50301",
                                        "JucePlugin_Build_VST=0",
                                        "JucePlugin_Build_VST3=0",
                                        "JucePlugin_Build_AU=0",
                                INSTALL_PATH = "$(HOME)/Applications";
                                PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.demorunner;
                                USE_HEADERMAP = NO; }; name = Debug; };
-               AAA32DF950DBB34322AB0692 = {isa = XCBuildConfiguration; buildSettings = {
+               878F062DF0F2D968EC322CF4 = {isa = XCBuildConfiguration; buildSettings = {
                                ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
                                ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
                                CLANG_CXX_LANGUAGE_STANDARD = "c++14";
                                        "JUCE_DEMO_RUNNER=1",
                                        "JUCE_UNIT_TESTS=1",
                                        "JUCER_XCODE_IPHONE_5BC26AE3=1",
-                                       "JUCE_APP_VERSION=5.2.1",
-                                       "JUCE_APP_VERSION_HEX=0x50201",
+                                       "JUCE_APP_VERSION=5.3.1",
+                                       "JUCE_APP_VERSION_HEX=0x50301",
                                        "JucePlugin_Build_VST=0",
                                        "JucePlugin_Build_VST3=0",
                                        "JucePlugin_Build_AU=0",
                                LLVM_LTO = YES;
                                PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.demorunner;
                                USE_HEADERMAP = NO; }; name = Release; };
-               211506D1B60914B8C1546597 = {isa = XCBuildConfiguration; buildSettings = {
+               49CDF00877DBD03D2C6D7313 = {isa = XCBuildConfiguration; buildSettings = {
                                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                                ALWAYS_SEARCH_USER_PATHS = NO;
                                CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
                                TARGETED_DEVICE_FAMILY = "1,2";
                                WARNING_CFLAGS = -Wreorder;
                                ZERO_LINK = NO; }; name = Debug; };
-               5B00E3812B10D12D66804140 = {isa = XCBuildConfiguration; buildSettings = {
+               4CADE461B4B845777C2F3084 = {isa = XCBuildConfiguration; buildSettings = {
                                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                                ALWAYS_SEARCH_USER_PATHS = NO;
                                CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
                                TARGETED_DEVICE_FAMILY = "1,2";
                                WARNING_CFLAGS = -Wreorder;
                                ZERO_LINK = NO; }; name = Release; };
-               8FFD14978945B15A63DA441C = {isa = PBXTargetDependency; target = 5C44D3B98501718D937EAA8C; };
-               E7D42B7F81AAAB7DE49DAE20 = {isa = XCConfigurationList; buildConfigurations = (
-                                       211506D1B60914B8C1546597,
-                                       5B00E3812B10D12D66804140, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
-               D8423C9D12EDCA5569929D2C = {isa = XCConfigurationList; buildConfigurations = (
-                                       0BF6FF13ABD310AA426C4D86,
-                                       AAA32DF950DBB34322AB0692, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
-               EB12964B44C1C7B6159FB179 = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (
-                                       0830C88F5BCD8EAC20E32CD3,
-                                       E774DAD5CD373E9117FA1C6C,
-                                       2DC1C2164642836F0AEA40A8, ); runOnlyForDeploymentPostprocessing = 0; };
-               D7CEBDA9ACAE974C9C78903D = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (
-                                       756A7AB6373D013FF081857B,
-                                       E93AB2D1FE2B626F8D206477,
-                                       17A4AA2C7BD1A5303EF23E4C,
-                                       73850D87E50FB5196EE6B422,
-                                       272C981B90E5FCF85FC2B356,
-                                       61A2A777A5E2165A58CB7FA1,
-                                       3A6BADD63BD2CD4C2A4B8B92,
-                                       BF2FAB5969AC733B0329C975,
-                                       FF0E86794C1852BE55EF2DE7,
-                                       A22B5F90E70672CBEEDBE4D4,
-                                       608C0EEE88E50CEB33FD93B0,
-                                       3B41F9F3BA57A45FDD2CF687,
-                                       8A90259D6376541FCCDBF59C,
-                                       32E555692EA88756C8AE33C4,
-                                       B6158CAAC9D313E28AC0DF0D,
-                                       1E614F5E3EC385511F4230C4,
-                                       801983262C42D57DC51ACF6B,
-                                       F664B60DDB169E8ACA354AF9,
-                                       76D886AA6B0E90D452F10F02,
-                                       F0CB20CC1945DAFF9E561761,
-                                       1E5DFED918A016879F0E4FB6,
-                                       534602D32BB67E55866BFD6B,
-                                       B03DADDEC5B4385D509471E8,
-                                       3C5CC8F258D9631CBABF41F3,
-                                       4AC737FF1A171EF7ED650753,
-                                       FFD08F7DE6EE7278D22A4D8D, ); runOnlyForDeploymentPostprocessing = 0; };
-               FC5B047114D0B62045C1432E = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (
-                                       886B639B447435FE448C23B9,
-                                       AC12EB87710816D88C3D5638,
-                                       5C9528020475526C0D988DC4,
-                                       7F1AA503C98CA6C7A871153F,
-                                       B81D3893E01BA6B347A524B4,
-                                       66CD55F2A348D8A949431DB3,
-                                       A937D294F46A3C68720BF01A,
-                                       6C6E157D6B635CEC54EDD4EC,
-                                       BEC5794CC1DF5965031123A3,
-                                       DA87B9D062E300CDF0AFAA8A,
-                                       9857BBAEFF58ABFDD46170F3,
-                                       BB5AADC46D641EB6C2EDD6C3,
-                                       14DE1ECE2F55AE0896428FFF,
-                                       315180ECB6489429EA1CB578,
-                                       F0701F95186DA3A40A886DB6,
-                                       006DB50986A0346D98807D97, ); runOnlyForDeploymentPostprocessing = 0; };
-               5C44D3B98501718D937EAA8C = {isa = PBXNativeTarget; buildConfigurationList = D8423C9D12EDCA5569929D2C; buildPhases = (
-                                       EB12964B44C1C7B6159FB179,
-                                       D7CEBDA9ACAE974C9C78903D,
-                                       FC5B047114D0B62045C1432E, ); buildRules = ( ); dependencies = (  ); name = "DemoRunner - App"; productName = DemoRunner; productReference = 2ED744F17B2133AC2EFEE9F9; productType = "com.apple.product-type.application"; };
-               1658833C7B558CFD9996D813 = {isa = PBXProject; buildConfigurationList = E7D42B7F81AAAB7DE49DAE20; attributes = { LastUpgradeCheck = 0830; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { 5C44D3B98501718D937EAA8C = { 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.iCloud = { enabled = 1; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 12C3AAFF06FB271063BD3774; projectDirPath = ""; projectRoot = ""; targets = (5C44D3B98501718D937EAA8C); };
+               82C712E3A2B72D3FE08871AB = {isa = PBXTargetDependency; target = AF4A5EF10D3A095A9074F9CF; };
+               F63BE64D6F90B83AFFFBC14F = {isa = XCConfigurationList; buildConfigurations = (
+                                       49CDF00877DBD03D2C6D7313,
+                                       4CADE461B4B845777C2F3084, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
+               77311CC6EFE85E7117AD3242 = {isa = XCConfigurationList; buildConfigurations = (
+                                       CEC200AA273D1626F466FC27,
+                                       878F062DF0F2D968EC322CF4, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
+               2077585B61D41BDA5967E25C = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (
+                                       B1776D2FEB204FAE5C17E4C7,
+                                       686146610021944DA9C987B8,
+                                       F657E50CA75FE6932E710CB0, ); runOnlyForDeploymentPostprocessing = 0; };
+               7C6E2E57520A67ACFE86097B = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (
+                                       F9EDB3A8F55A4499441401D6,
+                                       EACB962CC04BDC0369264A8F,
+                                       557BA8FDD37630DF5EB84EE0,
+                                       5CFCACD6AF608BDC2E1E8BD1,
+                                       9263171BCE90616A9F350405,
+                                       2EF49BC29DA0951B1C43070F,
+                                       8861132DCB0DE3F9EB0DD278,
+                                       CCDAEA12C17058099252FD3D,
+                                       28778136A8C09DBDC980CB72,
+                                       DA696766645C964870153095,
+                                       8F5FE1B5D44F55667509BC99,
+                                       3656169644FED0C525D5D30C,
+                                       2763512B6DFF68C0EEF72496,
+                                       480F45A17B4E83A26B1ACEF9,
+                                       3D8EECDED13F0A46A6FA8D3E,
+                                       E433C1C591D091AF71AD528E,
+                                       A5F8F9904580960794429360,
+                                       B298295E61E5DD800B814DAF,
+                                       A7E206DD280DC58E2A150642,
+                                       26260D259EFF13BD5044CD34,
+                                       591D5799ED6524DE9BD846D7,
+                                       D09859BDBC491A9932637715,
+                                       7EC8A06F9290B16DFB16E346,
+                                       33C96917E46535D30B17B483,
+                                       8AA7BB967216BDBFF0371267,
+                                       FD5B59B8A0B8258531421E60, ); runOnlyForDeploymentPostprocessing = 0; };
+               FB8E53AB54C36DCB3C3FC501 = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (
+                                       C8D093204643DE75CAA41A3F,
+                                       7286A5BB489F25E6E3CF63D4,
+                                       B6AB4CB9F0A0AD540028A3E1,
+                                       71F90E5ABB1112D2D92EAB59,
+                                       AB53895F1E4193A2C9B51DB6,
+                                       9CB6071FE1DD378F7C64C9F5,
+                                       1D98F6C4127BB7F0890645D6,
+                                       0B1AC7FEC205238C5701B086,
+                                       2EF15A7E6ECFD861D719276A,
+                                       9318D1152DE35146100C7594,
+                                       BA3F994E8752E7310789C02A,
+                                       06DA6875AC3E734378E374C5,
+                                       9F59844F463603E7C2467DC4,
+                                       C7D4E452620DF858B785BA82,
+                                       3D2D1CCFB4B682162034225E,
+                                       EDAD741A46FD4B3F002C96D3, ); runOnlyForDeploymentPostprocessing = 0; };
+               AF4A5EF10D3A095A9074F9CF = {isa = PBXNativeTarget; buildConfigurationList = 77311CC6EFE85E7117AD3242; buildPhases = (
+                                       2077585B61D41BDA5967E25C,
+                                       7C6E2E57520A67ACFE86097B,
+                                       FB8E53AB54C36DCB3C3FC501, ); buildRules = ( ); dependencies = (  ); name = "DemoRunner - App"; productName = DemoRunner; productReference = B953F5C249804F38B818AD2F; productType = "com.apple.product-type.application"; };
+               15C553274AB25531D0A16FBE = {isa = PBXProject; buildConfigurationList = F63BE64D6F90B83AFFFBC14F; attributes = { LastUpgradeCheck = 0830; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { AF4A5EF10D3A095A9074F9CF = { 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.iCloud = { enabled = 1; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 9979C8B054ED17C9E04C6BAB; projectDirPath = ""; projectRoot = ""; targets = (AF4A5EF10D3A095A9074F9CF); };
        };
-       rootObject = 1658833C7B558CFD9996D813;
+       rootObject = 15C553274AB25531D0A16FBE;
 }
index 241a0abbac16bfc7c051fbda6eab035ee584a4d8..a864c56f7547651f9e6b089d9b94123f12119a82 100644 (file)
@@ -22,9 +22,9 @@
     <key>CFBundleSignature</key>\r
     <string>????</string>\r
     <key>CFBundleShortVersionString</key>\r
-    <string>5.2.1</string>\r
+    <string>5.3.1</string>\r
     <key>CFBundleVersion</key>\r
-    <string>5.2.1</string>\r
+    <string>5.3.1</string>\r
     <key>NSHumanReadableCopyright</key>\r
     <string>Copyright (c) 2018 - ROLI Ltd.</string>\r
     <key>NSHighResolutionCapable</key>\r
index 5a95626f158a1b9b9a7f7cfa20142ae03a7be92c..5cfe6777ecb7a5ffaf86174f39d1e475e34d3cf9 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 \r
-<JUCERPROJECT name="DemoRunner" projectType="guiapp" jucerVersion="5.3.0" defines="JUCE_DEMO_RUNNER=1&#10;JUCE_UNIT_TESTS=1"\r
-              bundleIdentifier="com.roli.juce.demorunner" version="5.2.1" companyName="ROLI Ltd."\r
+<JUCERPROJECT name="DemoRunner" projectType="guiapp" jucerVersion="5.3.1" defines="JUCE_DEMO_RUNNER=1&#10;JUCE_UNIT_TESTS=1"\r
+              bundleIdentifier="com.roli.juce.demorunner" version="5.3.1" companyName="ROLI Ltd."\r
               companyCopyright="Copyright (c) 2018 - ROLI Ltd." companyWebsite="https://www.juce.com/"\r
               companyEmail="info@juce.com">\r
   <MAINGROUP id="G8kbr7" name="DemoRunner">\r
@@ -29,7 +29,8 @@
     </GROUP>\r
   </MAINGROUP>\r
   <EXPORTFORMATS>\r
-    <XCODE_MAC targetFolder="Builds/MacOSX" smallIcon="YyqWd2" bigIcon="YyqWd2">\r
+    <XCODE_MAC targetFolder="Builds/MacOSX" smallIcon="YyqWd2" bigIcon="YyqWd2"\r
+               extraCompilerFlags="-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -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 -Wno-ignored-qualifiers -Wunreachable-code">\r
       <CONFIGURATIONS>\r
         <CONFIGURATION isDebug="1" name="Debug"/>\r
         <CONFIGURATION isDebug="0" name="Release"/>\r
index 6b95c792336fd10e06b5e86c714663db80cfb20a..42a1698d04083f9279406c1cd48c630f3bf32ba0 100644 (file)
  //#define JUCE_JACK 0\r
 #endif\r
 \r
+#ifndef    JUCE_BELA\r
+ //#define JUCE_BELA 0\r
+#endif\r
+\r
 #ifndef    JUCE_USE_ANDROID_OBOE\r
  //#define JUCE_USE_ANDROID_OBOE 0\r
 #endif\r
index e8c08a04c85b4864c9d928aab6c693c3dc8f8cbc..55e3638b97e6280830b098432e36a011860a3ba8 100644 (file)
@@ -46,7 +46,7 @@
 namespace ProjectInfo\r
 {\r
     const char* const  projectName    = "DemoRunner";\r
-    const char* const  versionString  = "5.2.1";\r
-    const int          versionNumber  = 0x50201;\r
+    const char* const  versionString  = "5.3.1";\r
+    const int          versionNumber  = 0x50301;\r
 }\r
 #endif\r
index 844cd83eb98cd19e0e1bb1cbc5e8f5b056d67f02..c79f07bfca6203cd81541863ffe7d9a453510c15 100644 (file)
@@ -105,7 +105,7 @@ void registerDemos_One() noexcept
     REGISTER_DEMO (OscillatorDemo,            DSP,       false)\r
     REGISTER_DEMO (OverdriveDemo,             DSP,       false)\r
     #if JUCE_USE_SIMD\r
-     REGISTER_DEMO (SIMDRegisterDemo,          DSP,       false)\r
+     REGISTER_DEMO (SIMDRegisterDemo,         DSP,       false)\r
     #endif\r
     REGISTER_DEMO (StateVariableFilterDemo,   DSP,       false)\r
     REGISTER_DEMO (WaveShaperTanhDemo,        DSP,       false)\r
index d459204b547ad06c73bf32ce55df561f245de1e9..b8e8c9dfcba71aeb95ca777e789334bb40ded578 100644 (file)
@@ -51,7 +51,7 @@ JUCEDemos::DemoCategory& JUCEDemos::getCategory (const String& name)
 \r
 void JUCEDemos::registerDemo (std::function<Component*()> constructorCallback, const String& filePath, const String& category, bool isHeavyweight)\r
 {\r
-    auto f = findExamplesDirectoryFromExecutable (File::getSpecialLocation (File::SpecialLocationType::currentExecutableFile));\r
+    auto f = findExamplesDirectoryFromExecutable (File::getSpecialLocation (File::SpecialLocationType::currentApplicationFile));\r
 \r
     #if ! (JUCE_ANDROID || JUCE_IOS)\r
     if (f == File())\r
@@ -67,13 +67,15 @@ void JUCEDemos::registerDemo (std::function<Component*()> constructorCallback, c
 File JUCEDemos::findExamplesDirectoryFromExecutable (File exec)\r
 {\r
     int numTries = 15;\r
+    auto exampleDir = exec.getParentDirectory().getChildFile ("examples");\r
+\r
+    if (exampleDir.exists())\r
+        return exampleDir;\r
 \r
     while (exec.getFileName() != "examples" && numTries-- > 0)\r
         exec = exec.getParentDirectory();\r
-\r
     if (exec.getFileName() == "examples")\r
         return exec;\r
-\r
     return {};\r
 }\r
 \r
index fe21fe5e3912e7c36aa4ebeb7c877abeb8a0879a..68d93d43683fe7253b1005edcd88865c86c24089 100644 (file)
@@ -69,7 +69,7 @@ struct CodeContent    : public Component
         codeEditor.setScrollbarThickness (8);\r
 \r
         lookAndFeelChanged();\r
-    };\r
+    }\r
 \r
     void resized() override\r
     {\r
@@ -111,7 +111,7 @@ DemoContentComponent::DemoContentComponent (Component& mainComponent, std::funct
     addTab ("Code",     Colours::transparentBlack, codeContent = new CodeContent(), false);\r
    #endif\r
 \r
-    addTab ("Settings", Colours::transparentBlack, new SettingsContent (dynamic_cast<MainComponent&> (mainComponent)),           true);\r
+    addTab ("Settings", Colours::transparentBlack, new SettingsContent (dynamic_cast<MainComponent&> (mainComponent)), true);\r
 \r
     setTabBarDepth (40);\r
     lookAndFeelChanged();\r
@@ -135,7 +135,7 @@ void DemoContentComponent::setDemo (const String& category, int selectedDemoInde
         && (currentDemoIndex == selectedDemoIndex))\r
         return;\r
 \r
-    auto demo = JUCEDemos::getCategory (category).demos[selectedDemoIndex];\r
+    auto demo = JUCEDemos::getCategory (category).demos[(size_t) selectedDemoIndex];\r
 \r
    #if ! (JUCE_ANDROID || JUCE_IOS)\r
     codeContent->document.replaceAllContent (trimPIP (demo.demoFile.loadFileAsString()));\r
index c0f616295956ee23702ba7e338758a60e0de9f4c..d36aa047fe98fc2411532a4706717f7e1303cc2d 100644 (file)
@@ -170,7 +170,7 @@ public:
         if (selectedCategory.isEmpty())\r
         {\r
             if (isPositiveAndBelow (rowNumber, JUCEDemos::getCategories().size()))\r
-                g.drawFittedText (JUCEDemos::getCategories()[rowNumber].name,\r
+                g.drawFittedText (JUCEDemos::getCategories()[(size_t) rowNumber].name,\r
                                   bounds, Justification::centred, 1);\r
         }\r
         else\r
@@ -178,7 +178,7 @@ public:
             auto& category = JUCEDemos::getCategory (selectedCategory);\r
 \r
             if (isPositiveAndBelow (rowNumber, category.demos.size()))\r
-                g.drawFittedText (category.demos[rowNumber].demoFile.getFileName(),\r
+                g.drawFittedText (category.demos[(size_t) rowNumber].demoFile.getFileName(),\r
                                   bounds, Justification::centred, 1);\r
         }\r
     }\r
@@ -191,11 +191,11 @@ public:
 \r
     void selectedRowsChanged (int row) override\r
     {\r
-        if (row == -1)\r
+        if (row < 0)\r
             return;\r
 \r
         if (selectedCategory.isEmpty())\r
-            showCategory (JUCEDemos::getCategories()[row].name);\r
+            showCategory (JUCEDemos::getCategories()[(size_t) row].name);\r
         else\r
             demoHolder.setDemo (selectedCategory, row);\r
     }\r
@@ -249,6 +249,15 @@ MainComponent::MainComponent()
         demosPanel.showOrHide (false);\r
        #endif\r
 \r
+        if (isHeavyweight)\r
+        {\r
+           #if JUCE_MAC && USE_COREGRAPHICS_RENDERING\r
+            setRenderingEngine (1);\r
+           #else\r
+            setRenderingEngine (0);\r
+           #endif\r
+        }\r
+\r
         isShowingHeavyweightDemo = isHeavyweight;\r
         resized();\r
     });\r
@@ -393,6 +402,9 @@ void MainComponent::updateRenderingEngine (int renderingEngineIndex)
 {\r
     if (renderingEngineIndex == (renderingEngines.size() - 1))\r
     {\r
+        if (isShowingHeavyweightDemo)\r
+            return;\r
+\r
         openGLContext.attachTo (*getTopLevelComponent());\r
     }\r
     else\r
index c5ddf97bd195e0f691c04f7e299b6f237cac84d1..6a9d1576ab9a6456d7a9328f520b4f7937eb7e88 100644 (file)
 #include "DemoContentComponent.h"\r
 \r
 //==============================================================================\r
-/*\r
-    This component lives inside our window, and this is where you should put all\r
-    your controls and content.\r
-*/\r
 class MainComponent    : public Component\r
 {\r
 public:\r
index 82c8b2801d2217d8f78df520cb974e1e5c1edb45..bb93d765568f96f82221c1258d91f49b68cbccac 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             AnimationAppDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Simple animation application.\r
 \r
index 7a853e144285ed731c723041b75d1cf8794acdf5..8aa97a0790f46339c32492f2a00f1dc18eecdff5 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             AnimationDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Displays an animated draggable ball.\r
 \r
index 5f55ce8e74976442218d8b874a8b6ffcf62bb78d..dea790500ecc0a1a02753f1c8197df6d6eb06380 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             BouncingBallWavetableDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Wavetable synthesis with a bouncing ball.\r
 \r
index 17905557c6126c28ffa2e89f194ef03820faa118..301a619e1195d3ed63e8db8c021c88b384594bf0 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             CameraDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases camera features.\r
 \r
index d974b46cb8e0c307a24e1aeafee67835e477297a..2ff9cf3483c1017a6a54ea0e370243588a00e586 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             CodeEditorDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Displays a code editor.\r
 \r
index 80b7af913c549a94f6021b003dc7dd42e914107e..7944d2bee42580e8d9b362e43c3865c2576d7841 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             ComponentDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Displays a grid of lights.\r
 \r
index 05c343246d8a13b1b6737d36079d0e453679253f..c3a5e51eceeba7cef152d0d5aa508b6be2610370 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             ComponentTransformsDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Applies transformations to components.\r
 \r
index 68f1580b4441de18ab9dc493d321dd267935ae8f..4c56ccdf5baae74b02e4f0a61fcb034da8e9a216 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             DialogsDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Displays different types of dialog windows.\r
 \r
index b55a0b89b9edf35a00d899856d4f7de45c7395d7..8c4bafcc4d9050264881302d25fee9c35913c702 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             FlexBoxDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Responsive layouts using FlexBox.\r
 \r
index bb818a5e8937b425030c77237ee87cb1df55d269..647df1dda0baa896f30372a359efc89c7e197faa 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             FontsDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Displays different font styles and types.\r
 \r
index b027769ba69eff4f6233458808d83daa79c9ff19..b47247676a2c21bf2a130528f6c5c8391be7f861 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             GraphicsDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases various graphics features.\r
 \r
index acd668cee5bd5d5581b65132f2d18c936a82e32d..8b6a9f7eabcb2759d7708f614a71b72fa4b3eab5 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             GridDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Responsive layouts using Grid.\r
 \r
index 82846af9811d50a7bb17b5f0ff081f7fca0ade4a..39886227de9152c69de0a1851ab3e9ccb595e5d5 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             HelloWorldDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Simple HelloWorld application.\r
 \r
index 40e8912cd1c4752cf74f18ebb7a7bc323b6ccbe9..707e8a2ae00a65306a83a1b3079d2bb03d932043 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             ImagesDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Displays image files.\r
 \r
index 9a9a6c062dc6345e4f02cdd7b8b80f4f4555e436..b2a786f0c0027c79195efc173f62338a695c01e7 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             KeyMappingsDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases key mapping features.\r
 \r
index 80dd1d01eb5c26b6e0481ee1a1302281ae4f418f..752a242e434c608af436186ae06860e2d1386a37 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             LookAndFeelDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases custom look and feel components.\r
 \r
index f5ef6452a50f5114f4f10b67207c3e4fffaa852b..7f1049b95d750eda8309d527708081ac3f639593 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             MDIDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Displays and edits MDI files.\r
 \r
index 0f1d8d603ff7a41b5a3276a907ad496086c722f9..279e97f23eac065dadeeeb2b2c73db31c16ea65e 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             MenusDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases menu features.\r
 \r
index 16d2fc54ade9185a5ca126b06e5878f72928339a..b6a5ecc1563e210a9c5b56cba277300949bf9d91 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             MultiTouchDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases multi-touch features.\r
 \r
index 455940e93e67c19b7d27a1f0b4b75eb5e43cfefb..d2b458a46d9bb3e7dddf36ec0e9babbc93c1494e 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             OpenGLAppDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Simple OpenGL application.\r
 \r
@@ -147,7 +147,7 @@ public:
         vertexShader =\r
             "attribute vec4 position;\n"\r
             "attribute vec4 sourceColour;\n"\r
-            "attribute vec2 texureCoordIn;\n"\r
+            "attribute vec2 textureCoordIn;\n"\r
             "\n"\r
             "uniform mat4 projectionMatrix;\n"\r
             "uniform mat4 viewMatrix;\n"\r
@@ -158,7 +158,7 @@ public:
             "void main()\n"\r
             "{\n"\r
             "    destinationColour = sourceColour;\n"\r
-            "    textureCoordOut = texureCoordIn;\n"\r
+            "    textureCoordOut = textureCoordIn;\n"\r
             "    gl_Position = projectionMatrix * viewMatrix * position;\n"\r
             "}\n";\r
 \r
@@ -224,10 +224,10 @@ private:
     {\r
         Attributes (OpenGLContext& openGLContext, OpenGLShaderProgram& shaderProgram)\r
         {\r
-            position     .reset (createAttribute (openGLContext, shaderProgram, "position"));\r
-            normal       .reset (createAttribute (openGLContext, shaderProgram, "normal"));\r
-            sourceColour .reset (createAttribute (openGLContext, shaderProgram, "sourceColour"));\r
-            texureCoordIn.reset (createAttribute (openGLContext, shaderProgram, "texureCoordIn"));\r
+            position      .reset (createAttribute (openGLContext, shaderProgram, "position"));\r
+            normal        .reset (createAttribute (openGLContext, shaderProgram, "normal"));\r
+            sourceColour  .reset (createAttribute (openGLContext, shaderProgram, "sourceColour"));\r
+            textureCoordIn.reset (createAttribute (openGLContext, shaderProgram, "textureCoordIn"));\r
         }\r
 \r
         void enable (OpenGLContext& glContext)\r
@@ -250,10 +250,10 @@ private:
                 glContext.extensions.glEnableVertexAttribArray (sourceColour->attributeID);\r
             }\r
 \r
-            if (texureCoordIn.get() != nullptr)\r
+            if (textureCoordIn.get() != nullptr)\r
             {\r
-                glContext.extensions.glVertexAttribPointer (texureCoordIn->attributeID, 2, GL_FLOAT, GL_FALSE, sizeof (Vertex), (GLvoid*) (sizeof (float) * 10));\r
-                glContext.extensions.glEnableVertexAttribArray (texureCoordIn->attributeID);\r
+                glContext.extensions.glVertexAttribPointer (textureCoordIn->attributeID, 2, GL_FLOAT, GL_FALSE, sizeof (Vertex), (GLvoid*) (sizeof (float) * 10));\r
+                glContext.extensions.glEnableVertexAttribArray (textureCoordIn->attributeID);\r
             }\r
         }\r
 \r
@@ -262,10 +262,10 @@ private:
             if (position.get() != nullptr)       glContext.extensions.glDisableVertexAttribArray (position->attributeID);\r
             if (normal.get() != nullptr)         glContext.extensions.glDisableVertexAttribArray (normal->attributeID);\r
             if (sourceColour.get() != nullptr)   glContext.extensions.glDisableVertexAttribArray (sourceColour->attributeID);\r
-            if (texureCoordIn.get() != nullptr)  glContext.extensions.glDisableVertexAttribArray (texureCoordIn->attributeID);\r
+            if (textureCoordIn.get() != nullptr) glContext.extensions.glDisableVertexAttribArray (textureCoordIn->attributeID);\r
         }\r
 \r
-        ScopedPointer<OpenGLShaderProgram::Attribute> position, normal, sourceColour, texureCoordIn;\r
+        ScopedPointer<OpenGLShaderProgram::Attribute> position, normal, sourceColour, textureCoordIn;\r
 \r
     private:\r
         static OpenGLShaderProgram::Attribute* createAttribute (OpenGLContext& openGLContext,\r
index 94a46ca3dcb7b4ceeb8da8fc82901f1f24e798a3..64c2449318483edb3b23e215813ff9884ebd33e9 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             OpenGLDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Simple 3D OpenGL application.\r
 \r
index 9028deb8e6567467f6610c791b579eec4fcea4dd..e9d4ad573aaf30406bb15b0a4b9e72f680fc598c 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             OpenGLDemo2D\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Simple 2D OpenGL application.\r
 \r
index a521c5985f3f1a04e04644cf4738d7c61f869cad..0172886484d115a311f7539a8c38dbd2c215766d 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             PropertiesDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Displays various property components.\r
 \r
@@ -141,58 +141,27 @@ static Array<PropertyComponent*> createChoices (int howMany)
     StringArray choices;\r
     Array<var> choiceVars;\r
 \r
-    for (int i = 0; i < howMany; ++i)\r
+    for (int i = 0; i < 12; ++i)\r
     {\r
         choices.add ("Item " + String (i));\r
         choiceVars.add (i);\r
     }\r
 \r
     for (int i = 0; i < howMany; ++i)\r
-        comps.add (new ChoicePropertyComponent (Value (Random::getSystemRandom().nextInt (6)), "Choice Property " + String (i + 1), choices, choiceVars));\r
+        comps.add (new ChoicePropertyComponent (Value (Random::getSystemRandom().nextInt (12)), "Choice Property " + String (i + 1), choices, choiceVars));\r
+\r
+    for (int i = 0; i < howMany; ++i)\r
+        comps.add (new MultiChoicePropertyComponent (Value (Array<var>()), "Multi-Choice Property " + String (i + 1), choices, choiceVars));\r
 \r
     return comps;\r
 }\r
 \r
 //==============================================================================\r
-class PropertiesDemo   : public Component\r
-{\r
-public:\r
-    PropertiesDemo()\r
-    {\r
-        setOpaque (true);\r
-        addAndMakeVisible (propertyPanel);\r
-\r
-        propertyPanel.addSection ("Text Editors",      createTextEditors());\r
-        propertyPanel.addSection ("Sliders",           createSliders (3));\r
-        propertyPanel.addSection ("Choice Properties", createChoices (6));\r
-        propertyPanel.addSection ("Buttons & Toggles", createButtons (3));\r
-\r
-        setSize (750, 650);\r
-    }\r
-\r
-    void paint (Graphics& g) override\r
-    {\r
-        g.fillAll (getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::windowBackground,\r
-                                           Colour::greyLevel (0.8f)));\r
-    }\r
-\r
-    void resized() override\r
-    {\r
-        propertyPanel.setBounds (getLocalBounds().reduced (4));\r
-    }\r
-\r
-private:\r
-    PropertyPanel propertyPanel;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertiesDemo)\r
-};\r
-\r
-//==============================================================================\r
-class ConcertinaDemo   : public Component,\r
+class PropertiesDemo   : public Component,\r
                          private Timer\r
 {\r
 public:\r
-    ConcertinaDemo()\r
+    PropertiesDemo()\r
     {\r
         setOpaque (true);\r
         addAndMakeVisible (concertinaPanel);\r
@@ -212,7 +181,7 @@ public:
 \r
         {\r
             auto* panel = new PropertyPanel ("Choice Properties");\r
-            panel->addProperties (createChoices (12));\r
+            panel->addProperties (createChoices (3));\r
             addPanel (panel);\r
         }\r
 \r
@@ -222,6 +191,8 @@ public:
             addPanel (panel);\r
         }\r
 \r
+\r
+        setSize (750, 650);\r
         startTimer (300);\r
     }\r
 \r
@@ -251,5 +222,5 @@ private:
         concertinaPanel.setMaximumPanelSize (panel, panel->getTotalContentHeight());\r
     }\r
 \r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConcertinaDemo)\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertiesDemo)\r
 };\r
index 9e871376205c5b5512746f061d00ba3a9587a314..a05e4c9c84c8a551bfe47fd1ca0c78856b655b1f 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             VideoDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Plays video files.\r
 \r
index 8987b8e7d286ee2eb1d940bc0c1f084433f4dce2..f0ab4fe09e349a945727ff51f8d659c2f7fcedb7 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             WebBrowserDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Displays a web browser.\r
 \r
index 1c53013652986cf23959fdee938792670ac2da3c..bc978b3bff54e94a4bfaea0182fc251deb4f0398 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             WidgetsDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases various widgets.\r
 \r
index 3fd0f648305ea7df40e81559ad8e5b0856308e5f..e21d2537aa8e135c76f507f26254463033e238f9 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             WindowsDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Displays various types of windows.\r
 \r
index 9958f16ea0bc31229396b2a97f9b8a0830749980..7a41bfcb5a1681ee0900ca0c85b80b77ff7f6f6b 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             AUv3SynthPlugin\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      AUv3 synthesiser audio plugin.\r
 \r
@@ -193,15 +193,18 @@ public:
         roomSizeSlider.setRange (0.0, 1.0);\r
         addAndMakeVisible (roomSizeSlider);\r
 \r
-        auto* fileStream = getAssetsDirectory().getChildFile ("proaudio.path").createInputStream();\r
+        if (auto* assetStream = createAssetInputStream ("proaudio.path"))\r
+        {\r
+            ScopedPointer<InputStream> fileStream (assetStream);\r
 \r
-        Path proAudioPath;\r
-        proAudioPath.loadPathFromStream (*fileStream);\r
-        proAudioIcon.setPath (proAudioPath);\r
-        addAndMakeVisible (proAudioIcon);\r
+            Path proAudioPath;\r
+            proAudioPath.loadPathFromStream (*fileStream);\r
+            proAudioIcon.setPath (proAudioPath);\r
+            addAndMakeVisible (proAudioIcon);\r
 \r
-        auto proAudioIconColour = findColour (TextButton::buttonOnColourId);\r
-        proAudioIcon.setFill (FillType (proAudioIconColour));\r
+            auto proAudioIconColour = findColour (TextButton::buttonOnColourId);\r
+            proAudioIcon.setFill (FillType (proAudioIconColour));\r
+        }\r
 \r
         setSize (600, 400);\r
         startTimer (100);\r
@@ -314,13 +317,13 @@ public:
         for (auto i = 0; i < maxNumVoices; ++i)\r
             synth.addVoice (new SamplerVoice());\r
 \r
-        loadNewSampleFile (getAssetsDirectory().getChildFile ("singing.ogg"), "ogg");\r
+        loadNewSample (createAssetInputStream ("singing.ogg"), "ogg");\r
     }\r
 \r
     //==============================================================================\r
     bool isBusesLayoutSupported (const BusesLayout& layouts) const override\r
     {\r
-        return (layouts.getMainOutputChannels() == 2);\r
+        return (layouts.getMainOutputChannels() <= 2);\r
     }\r
 \r
     void prepareToPlay (double sampleRate, int estimatedMaxSizeOfBuffer) override\r
@@ -410,12 +413,6 @@ private:
         loadNewSample (soundBuffer, format);\r
     }\r
 \r
-    void loadNewSampleFile (const File& sampleFile, const char* format)\r
-    {\r
-        auto* soundBuffer = sampleFile.createInputStream();\r
-        loadNewSample (soundBuffer, format);\r
-    }\r
-\r
     void loadNewSample (InputStream* soundBuffer, const char* format)\r
     {\r
         ScopedPointer<AudioFormatReader> formatReader (formatManager.findFormatForFileExtension (format)->createReaderFor (soundBuffer, true));\r
index 14d256d8e25a902b8b92b3021f576a87cf1df1d8..3765353b8cc1e39e747773e4d1159c1dfc43d12b 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             ArpeggiatorPlugin\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Arpeggiator audio plugin.\r
 \r
index 8f003d9e39c28e2a83adbfc16a6df2dddae821d4..861d3f75fc8c52178028181c523f5d8291616724 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             AudioPluginDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Synthesiser audio plugin.\r
 \r
index 3c8e5499cb03b4355c5179410ed756ebdc3ad2c3..af8c215a6a9a5e664ff4c99363720854da7e7130 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             DSPModulePluginDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Audio plugin using the DSP module.\r
 \r
@@ -267,14 +267,20 @@ public:
 \r
         if (type != currentType)\r
         {\r
-            cabinetType.set(type);\r
+            cabinetType.set (type);\r
 \r
             auto maxSize = static_cast<size_t> (roundToInt (getSampleRate() * (8192.0 / 44100.0)));\r
+            auto assetName = (type == 0 ? "Impulse1.wav" : "Impulse2.wav");\r
 \r
-            if (type == 0)\r
-                convolution.loadImpulseResponse (getAssetsDirectory().getChildFile ("Impulse1.wav"), false, true, maxSize);\r
-            else\r
-                convolution.loadImpulseResponse (getAssetsDirectory().getChildFile ("Impulse2.wav"), false, true, maxSize);\r
+            ScopedPointer<InputStream> assetInputStream (createAssetInputStream (assetName));\r
+            if (assetInputStream != nullptr)\r
+            {\r
+                currentCabinetData.reset();\r
+                assetInputStream->readIntoMemoryBlock (currentCabinetData);\r
+\r
+                convolution.loadImpulseResponse (currentCabinetData.getData(), currentCabinetData.getSize(),\r
+                                                 false, true, maxSize);\r
+            }\r
         }\r
 \r
         cabinetIsBypassed = ! cabinetSimParam->get();\r
@@ -541,6 +547,7 @@ private:
     //==============================================================================\r
     dsp::ProcessorDuplicator<dsp::IIR::Filter<float>, dsp::IIR::Coefficients<float>> lowPassFilter, highPassFilter;\r
     dsp::Convolution convolution;\r
+    MemoryBlock currentCabinetData;\r
 \r
     static constexpr size_t numWaveShapers = 2;\r
     dsp::WaveShaper<float> waveShapers[numWaveShapers];\r
index d79bf1e8538b5f58404999e53c958dff2c5a15d8..f3eadbda679778c10e0d6cea8ff75444b355cc4d 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             GainPlugin\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Gain audio plugin.\r
 \r
index 6a8cc1797d0b52043efcfc74bd2a61b802f63b25..30588d4cc0d2ad515efd81f5603cb32a8f2af444 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             InterAppAudioEffectPlugin\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Inter-app audio effect plugin.\r
 \r
@@ -175,7 +175,7 @@ public:
 \r
     bool isBusesLayoutSupported (const BusesLayout& layouts) const override\r
     {\r
-        if (layouts.getMainInputChannelSet() != AudioChannelSet::stereo())\r
+        if (layouts.getMainInputChannels() > 2)\r
             return false;\r
 \r
         if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())\r
index 0f84047bc0f7070c9ab0211e601f981d2ba037e5..5db3df5695b12df7fd299d77d9d592f7db5f74bf 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             MultiOutSynthPlugin\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Multi-out synthesiser audio plugin.\r
 \r
@@ -89,7 +89,7 @@ public:
                 synth[midiChannel]->addVoice (new SamplerVoice());\r
         }\r
 \r
-        loadNewSample (getAssetsDirectory().getChildFile ("singing.ogg"));\r
+        loadNewSample (createAssetInputStream ("singing.ogg"), "ogg");\r
     }\r
 \r
     ~MultiOutSynth() {}\r
@@ -155,10 +155,9 @@ private:
         return output;\r
     }\r
 \r
-    void loadNewSample (const File& sampleFile)\r
+    void loadNewSample (InputStream* soundBuffer, const char* format)\r
     {\r
-        auto* soundBuffer = sampleFile.createInputStream();\r
-        ScopedPointer<AudioFormatReader> formatReader (formatManager.findFormatForFileExtension ("ogg")->createReaderFor (soundBuffer, true));\r
+        ScopedPointer<AudioFormatReader> formatReader (formatManager.findFormatForFileExtension (format)->createReaderFor (soundBuffer, true));\r
 \r
         BigInteger midiNotes;\r
         midiNotes.setRange (0, 126, true);\r
index abf3730abf34e948e4b78d362684363357e92e1c..ea7f26ab8307ad27f2f60c959e3a710f09e89fe2 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             NoiseGatePlugin\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Noise gate audio plugin.\r
 \r
index a26890e15daac9c676c91f10ac6f3abdc6ba8f80..06c37973b3e49feef1cbccf3722477728339ecc6 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             SamplerPlugin\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Sampler audio plugin.\r
 \r
@@ -56,6 +56,7 @@
 #include <iomanip>\r
 #include <sstream>\r
 #include <functional>\r
+#include <mutex>\r
 \r
 namespace IDs\r
 {\r
@@ -183,7 +184,7 @@ private:
 class MPESamplerSound final\r
 {\r
 public:\r
-    void setSample (ScopedPointer<Sample> value)\r
+    void setSample (std::unique_ptr<Sample> value)\r
     {\r
         sample = move (value);\r
         setLoopPointsInSeconds (loopPoints);\r
@@ -227,7 +228,7 @@ public:
     }\r
 \r
 private:\r
-    ScopedPointer<Sample> sample;\r
+    std::unique_ptr<Sample> sample;\r
     double centreFrequencyInHz { 440.0 };\r
     Range<double> loopPoints;\r
     LoopMode loopMode { LoopMode::none };\r
@@ -350,9 +351,9 @@ private:
         auto invAlpha = 1.0f - alpha;\r
 \r
         // just using a very simple linear interpolation here..\r
-        auto l = currentLevel * (inL[pos] * invAlpha + inL[nextPos] * alpha);\r
-        auto r = (inR != nullptr) ? currentLevel * (inR[pos] * invAlpha + inR[nextPos] * alpha)\r
-                                  : l;\r
+        auto l = static_cast<float> (currentLevel * (inL[pos] * invAlpha + inL[nextPos] * alpha));\r
+        auto r = static_cast<float> ((inR != nullptr) ? currentLevel * (inR[pos] * invAlpha + inR[nextPos] * alpha)\r
+                                                      : l);\r
 \r
         if (outR != nullptr)\r
         {\r
@@ -360,7 +361,9 @@ private:
             outR[writePos] += r;\r
         }\r
         else\r
+        {\r
             outL[writePos] += (l + r) * 0.5f;\r
+        }\r
 \r
         std::tie (currentSamplePos, currentDirection) = getNextState (currentFrequency,\r
                                                                       currentLoopBegin,\r
@@ -394,11 +397,11 @@ private:
         backward\r
     };\r
 \r
-    std::tuple<double, Direction> getNextState (double frequency,\r
-                                                double loopBegin,\r
-                                                double loopEnd) const\r
+    std::tuple<double, Direction> getNextState (double freq,\r
+                                                double begin,\r
+                                                double end) const\r
     {\r
-        auto nextPitchRatio = frequency / samplerSound->getCentreFrequencyInHz();\r
+        auto nextPitchRatio = freq / samplerSound->getCentreFrequencyInHz();\r
 \r
         auto nextSamplePos = currentSamplePos;\r
         auto nextDirection = currentDirection;\r
@@ -418,9 +421,9 @@ private:
         // Update current sample position, taking loop mode into account\r
         // If the loop mode was changed while we were travelling backwards, deal\r
         // with it gracefully.\r
-        if (nextDirection == Direction::backward && nextSamplePos < loopBegin)\r
+        if (nextDirection == Direction::backward && nextSamplePos < begin)\r
         {\r
-            nextSamplePos = loopBegin;\r
+            nextSamplePos = begin;\r
             nextDirection = Direction::forward;\r
 \r
             return { nextSamplePos, nextDirection };\r
@@ -429,13 +432,13 @@ private:
         if (samplerSound->getLoopMode() == LoopMode::none)\r
             return { nextSamplePos, nextDirection };\r
 \r
-        if (nextDirection == Direction::forward && loopEnd < nextSamplePos && !isTailingOff())\r
+        if (nextDirection == Direction::forward && end < nextSamplePos && !isTailingOff())\r
         {\r
             if (samplerSound->getLoopMode() == LoopMode::forward)\r
-                nextSamplePos = loopBegin;\r
+                nextSamplePos = begin;\r
             else if (samplerSound->getLoopMode() == LoopMode::pingpong)\r
             {\r
-                nextSamplePos = loopEnd;\r
+                nextSamplePos = end;\r
                 nextDirection = Direction::backward;\r
             }\r
         }\r
@@ -477,27 +480,27 @@ private:
 };\r
 \r
 template <typename Contents, typename... Args>\r
-ScopedPointer<ReferenceCountingAdapter<Contents>>\r
+std::unique_ptr<ReferenceCountingAdapter<Contents>>\r
 make_reference_counted (Args&&... args)\r
 {\r
     auto adapter = new ReferenceCountingAdapter<Contents> (std::forward<Args> (args)...);\r
-    return ScopedPointer<ReferenceCountingAdapter<Contents>> (adapter);\r
+    return std::unique_ptr<ReferenceCountingAdapter<Contents>> (adapter);\r
 }\r
 \r
 //==============================================================================\r
-inline ScopedPointer<AudioFormatReader> makeAudioFormatReader (AudioFormatManager& manager,\r
+inline std::unique_ptr<AudioFormatReader> makeAudioFormatReader (AudioFormatManager& manager,\r
                                                                  const void* sampleData,\r
                                                                  size_t dataSize)\r
 {\r
-    return ScopedPointer<AudioFormatReader> (manager.createReaderFor (new MemoryInputStream (sampleData,\r
+    return std::unique_ptr<AudioFormatReader> (manager.createReaderFor (new MemoryInputStream (sampleData,\r
                                                                                                dataSize,\r
                                                                                                false)));\r
 }\r
 \r
-inline ScopedPointer<AudioFormatReader> makeAudioFormatReader (AudioFormatManager& manager,\r
+inline std::unique_ptr<AudioFormatReader> makeAudioFormatReader (AudioFormatManager& manager,\r
                                                                  const File& file)\r
 {\r
-    return ScopedPointer<AudioFormatReader> (manager.createReaderFor (file));\r
+    return std::unique_ptr<AudioFormatReader> (manager.createReaderFor (file));\r
 }\r
 \r
 //==============================================================================\r
@@ -505,8 +508,8 @@ class AudioFormatReaderFactory
 {\r
 public:\r
     virtual ~AudioFormatReaderFactory() noexcept = default;\r
-    virtual ScopedPointer<AudioFormatReader> make (AudioFormatManager&) const = 0;\r
-    virtual ScopedPointer<AudioFormatReaderFactory> clone() const = 0;\r
+    virtual std::unique_ptr<AudioFormatReader> make (AudioFormatManager&) const = 0;\r
+    virtual std::unique_ptr<AudioFormatReaderFactory> clone() const = 0;\r
 };\r
 \r
 //==============================================================================\r
@@ -518,14 +521,14 @@ public:
           dataSize (dataSize)\r
     {}\r
 \r
-    ScopedPointer<AudioFormatReader> make (AudioFormatManager&manager ) const override\r
+    std::unique_ptr<AudioFormatReader> make (AudioFormatManager&manager ) const override\r
     {\r
         return makeAudioFormatReader (manager, sampleData, dataSize);\r
     }\r
 \r
-    ScopedPointer<AudioFormatReaderFactory> clone() const override\r
+    std::unique_ptr<AudioFormatReaderFactory> clone() const override\r
     {\r
-        return ScopedPointer<AudioFormatReaderFactory> (new MemoryAudioFormatReaderFactory (*this));\r
+        return std::unique_ptr<AudioFormatReaderFactory> (new MemoryAudioFormatReaderFactory (*this));\r
     }\r
 \r
 private:\r
@@ -541,14 +544,14 @@ public:
         : file (std::move (file))\r
     {}\r
 \r
-    ScopedPointer<AudioFormatReader> make (AudioFormatManager& manager) const override\r
+    std::unique_ptr<AudioFormatReader> make (AudioFormatManager& manager) const override\r
     {\r
         return makeAudioFormatReader (manager, file);\r
     }\r
 \r
-    ScopedPointer<AudioFormatReaderFactory> clone() const override\r
+    std::unique_ptr<AudioFormatReaderFactory> clone() const override\r
     {\r
-        return ScopedPointer<AudioFormatReaderFactory> (new FileAudioFormatReaderFactory (*this));\r
+        return std::unique_ptr<AudioFormatReaderFactory> (new FileAudioFormatReaderFactory (*this));\r
     }\r
 \r
 private:\r
@@ -625,8 +628,8 @@ public:
     {\r
     public:\r
         virtual ~Listener() noexcept = default;\r
-        virtual void totalRangeChanged   (Range<double> value) {}\r
-        virtual void visibleRangeChanged (Range<double> value) {}\r
+        virtual void totalRangeChanged   (Range<double>) {}\r
+        virtual void visibleRangeChanged (Range<double>) {}\r
     };\r
 \r
     VisibleRangeDataModel()\r
@@ -691,8 +694,7 @@ public:
     }\r
 \r
 private:\r
-    void valueTreePropertyChanged (ValueTree &treeWhosePropertyHasChanged,\r
-                                   const Identifier &property) override\r
+    void valueTreePropertyChanged (ValueTree&, const Identifier& property) override\r
     {\r
         if (property == IDs::totalRange)\r
         {\r
@@ -727,13 +729,13 @@ public:
     {\r
     public:\r
         virtual ~Listener() noexcept = default;\r
-        virtual void synthVoicesChanged (int value) {}\r
-        virtual void voiceStealingEnabledChanged (bool value) {}\r
-        virtual void legacyModeEnabledChanged (bool value) {}\r
-        virtual void mpeZoneLayoutChanged (const MPEZoneLayout& value) {}\r
-        virtual void legacyFirstChannelChanged (int value) {}\r
-        virtual void legacyLastChannelChanged (int value) {}\r
-        virtual void legacyPitchbendRangeChanged (int value) {}\r
+        virtual void synthVoicesChanged (int) {}\r
+        virtual void voiceStealingEnabledChanged (bool) {}\r
+        virtual void legacyModeEnabledChanged (bool) {}\r
+        virtual void mpeZoneLayoutChanged (const MPEZoneLayout&) {}\r
+        virtual void legacyFirstChannelChanged (int) {}\r
+        virtual void legacyLastChannelChanged (int) {}\r
+        virtual void legacyPitchbendRangeChanged (int) {}\r
     };\r
 \r
     MPESettingsDataModel()\r
@@ -852,8 +854,7 @@ public:
     }\r
 \r
 private:\r
-    void valueTreePropertyChanged (ValueTree &treeWhosePropertyHasChanged,\r
-                                   const Identifier &property) override\r
+    void valueTreePropertyChanged (ValueTree&, const Identifier& property) override\r
     {\r
         if (property == IDs::synthVoices)\r
         {\r
@@ -918,10 +919,10 @@ public:
     {\r
     public:\r
         virtual ~Listener() noexcept = default;\r
-        virtual void sampleReaderChanged (std::shared_ptr<AudioFormatReaderFactory> value) {}\r
-        virtual void centreFrequencyHzChanged (double value) {}\r
-        virtual void loopModeChanged (LoopMode value) {}\r
-        virtual void loopPointsSecondsChanged (Range<double> value) {}\r
+        virtual void sampleReaderChanged (std::shared_ptr<AudioFormatReaderFactory>) {}\r
+        virtual void centreFrequencyHzChanged (double) {}\r
+        virtual void loopModeChanged (LoopMode) {}\r
+        virtual void loopPointsSecondsChanged (Range<double>) {}\r
     };\r
 \r
     explicit DataModel (AudioFormatManager& audioFormatManager)\r
@@ -951,12 +952,12 @@ public:
         return *this;\r
     }\r
 \r
-    ScopedPointer<AudioFormatReader> getSampleReader() const\r
+    std::unique_ptr<AudioFormatReader> getSampleReader() const\r
     {\r
         return sampleReader != nullptr ? sampleReader.get()->make (*audioFormatManager) : nullptr;\r
     }\r
 \r
-    void setSampleReader (ScopedPointer<AudioFormatReaderFactory> readerFactory,\r
+    void setSampleReader (std::unique_ptr<AudioFormatReaderFactory> readerFactory,\r
                           UndoManager* undoManager)\r
     {\r
         sampleReader.setValue (move (readerFactory), undoManager);\r
@@ -966,8 +967,8 @@ public:
 \r
     double getSampleLengthSeconds() const\r
     {\r
-        if (auto sampleReader = getSampleReader())\r
-            return sampleReader->lengthInSamples / sampleReader->sampleRate;\r
+        if (auto r = getSampleReader())\r
+            return r->lengthInSamples / r->sampleRate;\r
 \r
         return 1.0;\r
     }\r
@@ -1031,8 +1032,7 @@ public:
     }\r
 \r
 private:\r
-    void valueTreePropertyChanged (ValueTree &treeWhosePropertyHasChanged,\r
-                                   const Identifier &property) override\r
+    void valueTreePropertyChanged (ValueTree&, const Identifier& property) override\r
     {\r
         if (property == IDs::sampleReader)\r
         {\r
@@ -1438,7 +1438,8 @@ private:
 \r
         newPath.startNewSubPath (bounds.getBottomLeft().toFloat());\r
         newPath.lineTo (bounds.getBottomRight().toFloat());\r
-        Point<float> apex (bounds.getX() + (bounds.getWidth() / 2), bounds.getBottom() - triHeight);\r
+        Point<float> apex (static_cast<float> (bounds.getX() + (bounds.getWidth() / 2)),\r
+                           static_cast<float> (bounds.getBottom() - triHeight));\r
         newPath.lineTo (apex);\r
         newPath.closeSubPath();\r
 \r
@@ -1459,7 +1460,7 @@ private:
 \r
     bool hitTest (int x, int y) override\r
     {\r
-        return path.contains (x, y);\r
+        return path.contains ((float) x, (float) y);\r
     }\r
 \r
     void mouseDown (const MouseEvent& e) override\r
@@ -1511,14 +1512,14 @@ private:
                                            0,\r
                                            bg.darker(),\r
                                            0,\r
-                                           getHeight(),\r
+                                           (float) getHeight(),\r
                                            false));\r
 \r
         g.fillAll();\r
         g.setColour (bg.brighter());\r
-        g.drawHorizontalLine (0, 0, getWidth());\r
+        g.drawHorizontalLine (0, 0.0f, (float) getWidth());\r
         g.setColour (bg.darker());\r
-        g.drawHorizontalLine (1, 0, getWidth());\r
+        g.drawHorizontalLine (1, 0.0f, (float) getWidth());\r
         g.setColour (Colours::lightgrey);\r
 \r
         auto minLog = std::ceil (std::log10 (visibleRange.getVisibleRange().getLength() / maxDivisions));\r
@@ -1533,15 +1534,15 @@ private:
                               / visibleRange.getVisibleRange().getLength();\r
 \r
             std::ostringstream out_stream;\r
-            out_stream << std::setprecision (precision) << time;\r
+            out_stream << std::setprecision (roundToInt (precision)) << roundToInt (time);\r
 \r
             g.drawText (out_stream.str(),\r
-                        Rectangle<int> (Point<int> (xPos + 3, 0),\r
-                                        Point<int> (xPos + minDivisionWidth, getHeight())),\r
+                        Rectangle<int> (Point<int> (roundToInt (xPos) + 3, 0),\r
+                                        Point<int> (roundToInt (xPos + minDivisionWidth), getHeight())),\r
                         Justification::centredLeft,\r
                         false);\r
 \r
-            g.drawVerticalLine (xPos, 2, getHeight());\r
+            g.drawVerticalLine (roundToInt (xPos), 2.0f, (float) getHeight());\r
         }\r
     }\r
 \r
@@ -1566,7 +1567,7 @@ private:
         visibleRange.setVisibleRange (range, nullptr);\r
     }\r
 \r
-    void visibleRangeChanged (Range<double> value) override\r
+    void visibleRangeChanged (Range<double>) override\r
     {\r
         repaint();\r
     }\r
@@ -1610,7 +1611,7 @@ private:
         positionLoopPointMarkers();\r
     }\r
 \r
-    void loopPointMouseDown (LoopPointMarker& marker, const MouseEvent& e)\r
+    void loopPointMouseDown (LoopPointMarker&, const MouseEvent&)\r
     {\r
         loopPointsOnMouseDown = dataModel.getLoopPointsSeconds();\r
         undoManager->beginNewTransaction();\r
@@ -1634,12 +1635,12 @@ private:
         dataModel.setLoopPointsSeconds (newLoopRange, undoManager);\r
     }\r
 \r
-    void loopPointsSecondsChanged (Range<double> value) override\r
+    void loopPointsSecondsChanged (Range<double>) override\r
     {\r
         positionLoopPointMarkers();\r
     }\r
 \r
-    void visibleRangeChanged      (Range<double> value) override\r
+    void visibleRangeChanged (Range<double>) override\r
     {\r
         positionLoopPointMarkers();\r
     }\r
@@ -1666,7 +1667,7 @@ private:
             auto ptr  = std::get<0> (tup);\r
             auto time = std::get<1> (tup);\r
             ptr->setSize (halfMarkerWidth * 2, getHeight());\r
-            ptr->setTopLeftPosition (timeToXPosition (time) - halfMarkerWidth, 0);\r
+            ptr->setTopLeftPosition (roundToInt (timeToXPosition (time) - halfMarkerWidth), 0);\r
         }\r
     }\r
 \r
@@ -1700,7 +1701,7 @@ private:
 \r
         for (auto position : provider())\r
         {\r
-            g.drawVerticalLine (timeToXPosition (position), 0, getHeight());\r
+            g.drawVerticalLine (roundToInt (timeToXPosition (position)), 0.0f, (float) getHeight());\r
         }\r
     }\r
 \r
@@ -1753,7 +1754,7 @@ private:
         if (numChannels == 0)\r
         {\r
             g.setColour (Colours::white);\r
-            g.drawFittedText ("No File Loaded", getLocalBounds(), Justification::centred, 1.0f);\r
+            g.drawFittedText ("No File Loaded", getLocalBounds(), Justification::centred, 1);\r
             return;\r
         }\r
 \r
@@ -1888,7 +1889,7 @@ public:
         {\r
             undoManager->beginNewTransaction();\r
             auto readerFactory = new FileAudioFormatReaderFactory (fc.getResult());\r
-            dataModel.setSampleReader (ScopedPointer<AudioFormatReaderFactory> (readerFactory),\r
+            dataModel.setSampleReader (std::unique_ptr<AudioFormatReaderFactory> (readerFactory),\r
                                        undoManager);\r
         };\r
 \r
@@ -2021,7 +2022,7 @@ struct ProcessorState
     int legacyPitchbendRange;\r
     bool voiceStealingEnabled;\r
     MPEZoneLayout mpeZoneLayout;\r
-    ScopedPointer<AudioFormatReaderFactory> readerFactory;\r
+    std::unique_ptr<AudioFormatReaderFactory> readerFactory;\r
     Range<double> loopPointsSeconds;\r
     double centreFrequencyHz;\r
     LoopMode loopMode;\r
@@ -2062,12 +2063,20 @@ public:
     SamplerAudioProcessor()\r
         : AudioProcessor (BusesProperties().withOutput ("Output", AudioChannelSet::stereo(), true))\r
     {\r
+        if (auto* asset = createAssetInputStream ("cello.wav"))\r
+        {\r
+            ScopedPointer<InputStream> inputStream (asset);\r
+            inputStream->readIntoMemoryBlock (mb);\r
+\r
+            readerFactory.reset (new MemoryAudioFormatReaderFactory (mb.getData(), mb.getSize()));\r
+        }\r
+\r
         // Set up initial sample, which we load from a binary resource\r
         AudioFormatManager manager;\r
         manager.registerBasicFormats();\r
         auto reader = readerFactory->make (manager);\r
         auto sound = samplerSound.load();\r
-        auto sample = ScopedPointer<Sample> (new Sample (*reader, 10.0));\r
+        auto sample = std::unique_ptr<Sample> (new Sample (*reader, 10.0));\r
         auto lengthInSeconds = sample->getLength() / sample->getSampleRate();\r
         sound->setLoopPointsInSeconds ({lengthInSeconds * 0.1, lengthInSeconds * 0.9 });\r
         sound->setSample (move (sample));\r
@@ -2077,7 +2086,7 @@ public:
             synthesiser.addVoice (new MPESamplerVoice (sound));\r
     }\r
 \r
-    void prepareToPlay (double sampleRate, int samplesPerBlock) override\r
+    void prepareToPlay (double sampleRate, int) override\r
     {\r
         synthesiser.setCurrentPlaybackSampleRate (sampleRate);\r
     }\r
@@ -2172,25 +2181,26 @@ public:
         // Update the current playback positions\r
         for (auto i = 0; i != maxVoices; ++i)\r
         {\r
-            MPESamplerVoice* voicePtr = nullptr;\r
-            playbackPositions[i] = (i < numVoices && (voicePtr = dynamic_cast<MPESamplerVoice*> (synthesiser.getVoice (i))))\r
-                                    ? voicePtr->getCurrentSamplePosition() / loadedSamplerSound->getSample()->getSampleRate()\r
-                                    : 0;\r
+            auto* voicePtr = dynamic_cast<MPESamplerVoice*> (synthesiser.getVoice (i));\r
+\r
+            if (i < numVoices && voicePtr != nullptr)\r
+                playbackPositions[i] = static_cast<float> (voicePtr->getCurrentSamplePosition() / loadedSamplerSound->getSample()->getSampleRate());\r
+            else\r
+                playbackPositions[i] = 0.0f;\r
         }\r
     }\r
 \r
     // These should be called from the GUI thread, and will block until the\r
     // command buffer has enough room to accept a command.\r
-    void setSample (ScopedPointer<AudioFormatReaderFactory> readerFactory,\r
-                                           AudioFormatManager& formatManager)\r
+    void setSample (std::unique_ptr<AudioFormatReaderFactory> fact, AudioFormatManager& formatManager)\r
     {\r
         class SetSampleCommand\r
         {\r
         public:\r
-            SetSampleCommand (ScopedPointer<AudioFormatReaderFactory> readerFactory,\r
-                              ScopedPointer<Sample> sample,\r
-                              std::vector<ScopedPointer<MPESamplerVoice>> newVoices)\r
-                : readerFactory (move (readerFactory)),\r
+            SetSampleCommand (std::unique_ptr<AudioFormatReaderFactory> r,\r
+                              std::unique_ptr<Sample> sample,\r
+                              std::vector<std::unique_ptr<MPESamplerVoice>> newVoices)\r
+                : readerFactory (move (r)),\r
                   sample (move (sample)),\r
                   newVoices (move (newVoices))\r
             {}\r
@@ -2210,31 +2220,31 @@ public:
             }\r
 \r
         private:\r
-            ScopedPointer<AudioFormatReaderFactory> readerFactory;\r
-            ScopedPointer<Sample> sample;\r
-            std::vector<ScopedPointer<MPESamplerVoice>> newVoices;\r
+            std::unique_ptr<AudioFormatReaderFactory> readerFactory;\r
+            std::unique_ptr<Sample> sample;\r
+            std::vector<std::unique_ptr<MPESamplerVoice>> newVoices;\r
         };\r
 \r
         // Note that all allocation happens here, on the main message thread. Then,\r
         // we transfer ownership across to the audio thread.\r
         auto loadedSamplerSound = samplerSound.load();\r
-        std::vector<ScopedPointer<MPESamplerVoice>> newSamplerVoices;\r
+        std::vector<std::unique_ptr<MPESamplerVoice>> newSamplerVoices;\r
         newSamplerVoices.reserve (maxVoices);\r
 \r
         for (auto i = 0; i != maxVoices; ++i)\r
             newSamplerVoices.emplace_back (new MPESamplerVoice (loadedSamplerSound));\r
 \r
-        if (readerFactory == nullptr)\r
+        if (fact == nullptr)\r
         {\r
-            pushCommand (SetSampleCommand (move (readerFactory),\r
+            pushCommand (SetSampleCommand (move (fact),\r
                                            nullptr,\r
                                            move (newSamplerVoices)));\r
         }\r
         else\r
         {\r
-            auto reader = readerFactory->make (formatManager);\r
-            pushCommand (SetSampleCommand (move (readerFactory),\r
-                                           ScopedPointer<Sample> (new Sample (*reader, 10.0)),\r
+            auto reader = fact->make (formatManager);\r
+            pushCommand (SetSampleCommand (move (fact),\r
+                                           std::unique_ptr<Sample> (new Sample (*reader, 10.0)),\r
                                            move (newSamplerVoices)));\r
         }\r
     }\r
@@ -2307,7 +2317,7 @@ public:
         class SetNumVoicesCommand\r
         {\r
         public:\r
-            SetNumVoicesCommand (std::vector<ScopedPointer<MPESamplerVoice>> newVoices)\r
+            SetNumVoicesCommand (std::vector<std::unique_ptr<MPESamplerVoice>> newVoices)\r
                 : newVoices (move (newVoices))\r
             {}\r
 \r
@@ -2325,12 +2335,12 @@ public:
             }\r
 \r
         private:\r
-            std::vector<ScopedPointer<MPESamplerVoice>> newVoices;\r
+            std::vector<std::unique_ptr<MPESamplerVoice>> newVoices;\r
         };\r
 \r
         numberOfVoices = std::min (maxVoices, numberOfVoices);\r
         auto loadedSamplerSound = samplerSound.load();\r
-        std::vector<ScopedPointer<MPESamplerVoice>> newSamplerVoices;\r
+        std::vector<std::unique_ptr<MPESamplerVoice>> newSamplerVoices;\r
         newSamplerVoices.reserve (numberOfVoices);\r
 \r
         for (auto i = 0; i != numberOfVoices; ++i)\r
@@ -2440,8 +2450,8 @@ private:
         {\r
             jassert (files.size() == 1);\r
             undoManager.beginNewTransaction();\r
-            auto readerFactory = new FileAudioFormatReaderFactory (files[0]);\r
-            dataModel.setSampleReader (ScopedPointer<AudioFormatReaderFactory> (readerFactory),\r
+            auto r = new FileAudioFormatReaderFactory (files[0]);\r
+            dataModel.setSampleReader (std::unique_ptr<AudioFormatReaderFactory> (r),\r
                                        &undoManager);\r
 \r
         }\r
@@ -2485,22 +2495,22 @@ private:
                 setProcessorMPEMode();\r
         }\r
 \r
-        void mpeZoneLayoutChanged (const MPEZoneLayout& value) override\r
+        void mpeZoneLayoutChanged (const MPEZoneLayout&) override\r
         {\r
             setProcessorMPEMode();\r
         }\r
 \r
-        void legacyFirstChannelChanged (int value) override\r
+        void legacyFirstChannelChanged (int) override\r
         {\r
             setProcessorLegacyMode();\r
         }\r
 \r
-        void legacyLastChannelChanged (int value) override\r
+        void legacyLastChannelChanged (int) override\r
         {\r
             setProcessorLegacyMode();\r
         }\r
 \r
-        void legacyPitchbendRangeChanged (int value) override\r
+        void legacyPitchbendRangeChanged (int) override\r
         {\r
             setProcessorLegacyMode();\r
         }\r
@@ -2559,12 +2569,12 @@ private:
     };\r
 \r
     template <typename Func>\r
-    static ScopedPointer<Command> make_command (Func&& func)\r
+    static std::unique_ptr<Command> make_command (Func&& func)\r
     {\r
-        return ScopedPointer<TemplateCommand<Func>> (new TemplateCommand<Func> (std::forward<Func> (func)));\r
+        return std::unique_ptr<TemplateCommand<Func>> (new TemplateCommand<Func> (std::forward<Func> (func)));\r
     }\r
 \r
-    using CommandFifo = MoveOnlyFifo<ScopedPointer<Command>>;\r
+    using CommandFifo = MoveOnlyFifo<std::unique_ptr<Command>>;\r
 \r
     class OutgoingBufferCleaner  : public Timer\r
     {\r
@@ -2604,7 +2614,8 @@ private:
     CommandFifo outgoingCommands;\r
     OutgoingBufferCleaner outgoingBufferCleaner { outgoingCommands };\r
 \r
-    ScopedPointer<AudioFormatReaderFactory> readerFactory { new FileAudioFormatReaderFactory (getAssetsDirectory().getChildFile ("cello.wav")) };\r
+    MemoryBlock mb;\r
+    std::unique_ptr<AudioFormatReaderFactory> readerFactory;\r
     AtomicSharedPtr<MPESamplerSound> samplerSound { std::make_shared<MPESamplerSound>() };\r
     MPESynthesiser synthesiser;\r
 \r
index 6418cdc2fad8f0cd02300c7971b10075e003d7b8..91ed5bea702900e3ed60b32e79fe22b668097f6d 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             SurroundPlugin\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Surround audio plugin.\r
 \r
index 58e33b29010a379cb08e193a40ce967e4e6c2f08..349977df4174786689af2366d1da67f984bca9e5 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             AnalyticsCollectionDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Collects analytics data.\r
 \r
index f98379cf148920fdb5f77383ed04303dda4dd878..362f98c89a3a13bb248ce3c93c7350426f927718 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             Box2DDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases 2D graphics features.\r
 \r
index 9e11974226fd1f2e9f479eb99113001eb8473a83..704abaf493bbbfc2e58d5a7c60dbca523eb782ee 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             ChildProcessDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Launches applications as child processes.\r
 \r
index 1ec68d66e1402c21920d201191e1847822e42fa4..3d5d9810d6bd757446a1a9c1d907be13e10859f4 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             CryptographyDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Encrypts and decrypts data.\r
 \r
index 14a867e6fd03a16db6b83e1271a306a92eef3ff2..d70c78afe3d8c1f198906c9aea0312f0d9f7ea35 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             InAppPurchasesDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases in-app purchases features. To run this demo you must enable the\r
                    "In-App Purchases Capability" option in the Projucer exporter.\r
@@ -380,13 +380,11 @@ public:
 \r
                 setInterceptsMouseClicks (! hasBeenPurchased, ! hasBeenPurchased);\r
 \r
-                auto imageFile = getAssetsDirectory().getChildFile ("Purchases").getChildFile (imageResourceName);\r
-\r
+                if (auto* assetStream = createAssetInputStream (String ("Purchases/" + String (imageResourceName)).toRawUTF8()))\r
                 {\r
-                    ScopedPointer<FileInputStream> imageData (imageFile.createInputStream());\r
+                    ScopedPointer<InputStream> fileStream (assetStream);\r
 \r
-                    if (imageData.get() != nullptr)\r
-                        avatar = PNGImageFormat().decodeImage (*imageData);\r
+                    avatar = PNGImageFormat().decodeImage (*fileStream);\r
                 }\r
             }\r
         }\r
@@ -552,17 +550,20 @@ private:
     //==============================================================================\r
     void playStopPhrase()\r
     {\r
-        MemoryOutputStream resourceName;\r
-\r
         auto idx = voiceListBox.getSelectedRow();\r
         if (isPositiveAndBelow (idx, soundNames.size()))\r
         {\r
-            resourceName << soundNames[idx] << phraseListBox.getSelectedRow() << ".ogg";\r
+            auto assetName = "Purchases/" + soundNames[idx] + String (phraseListBox.getSelectedRow()) + ".ogg";\r
+\r
+            if (auto* assetStream = createAssetInputStream (assetName.toRawUTF8()))\r
+            {\r
+                ScopedPointer<InputStream> fileStream (assetStream);\r
 \r
-            auto file = getAssetsDirectory().getChildFile ("Purchases").getChildFile (resourceName.toString().toRawUTF8());\r
+                currentPhraseData.reset();\r
+                fileStream->readIntoMemoryBlock (currentPhraseData);\r
 \r
-            if (file.exists())\r
-                player.play (file);\r
+                player.play (currentPhraseData.getData(), currentPhraseData.getSize());\r
+            }\r
         }\r
     }\r
 \r
@@ -571,7 +572,7 @@ private:
 \r
     Label phraseLabel                          { "phraseLabel", NEEDS_TRANS ("Phrases:") };\r
     ListBox phraseListBox                      { "phraseListBox" };\r
-    ScopedPointer<ListBoxModel> phraseModel  { new PhraseModel() };\r
+    ScopedPointer<ListBoxModel> phraseModel    { new PhraseModel() };\r
     TextButton playStopButton                  { "Play" };\r
 \r
     SoundPlayer player;\r
@@ -580,7 +581,9 @@ private:
 \r
     Label voiceLabel                           { "voiceLabel", NEEDS_TRANS ("Voices:") };\r
     ListBox voiceListBox                       { "voiceListBox" };\r
-    ScopedPointer<VoiceModel> voiceModel     { new VoiceModel (purchases) };\r
+    ScopedPointer<VoiceModel> voiceModel       { new VoiceModel (purchases) };\r
+\r
+    MemoryBlock currentPhraseData;\r
 \r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InAppPurchasesDemo)\r
 };\r
index 53971ee5d80030ec2752fff3ce4eec69a7483ecf..6a5749a558773afda6126b0198a22c3cac7fff86 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             JavaScriptDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases JavaScript features.\r
 \r
index 04d6774a7fce5f8621bb6bd72d082fe85fec1466..627b2244443a20923ff7fd2705d93a3e0e5ed400 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             LiveConstantDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Demonstrates the live constant macro.\r
 \r
index 1e1bf0ddcd0886b7047af390762c9ff4b1bc2ccf..0d7bf6e427c357bd64263fc4d5dd9a0e5b0784fb 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             MultithreadingDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Demonstrates multi-threading.\r
 \r
index 48a460a13c58483917dd67c7314a2549330e75fd..bbfb348ca584483b833d87e0df7bec8f7f3bca48 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             NetworkingDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases networking features.\r
 \r
index e6678d40be46252b6ca6d3d9aeca0a62e514f4e8..d29cb5523df9d6a2d994e4f268b858e02b359d50 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             OSCDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Application using the OSC protocol.\r
 \r
index 780455dc96182eb9963c0452a7c02298fa39281e..20cc256946e67c716fc4190bbdb3b0b7f36748dc 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             PushNotificationsDemo\r
  version:          2.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases push notifications features. To run this demo you must enable the\r
                    "Push Notifications Capability" option in the Projucer exporter.\r
@@ -957,7 +957,7 @@ private:
             setWantsKeyboardFocus (true);\r
         }\r
 \r
-        void addRowComponent (RowComponent *rc)\r
+        void addRowComponent (RowComponentrc)\r
         {\r
             rowComponents.add (rc);\r
             addAndMakeVisible (rc);\r
@@ -967,14 +967,14 @@ private:
         {\r
             auto totalRowUnits = 0;\r
 \r
-            for (auto &rc : rowComponents)\r
+            for (autorc : rowComponents)\r
                 totalRowUnits += rc->rowUnits;\r
 \r
             auto rowHeight = getHeight() / totalRowUnits;\r
 \r
             auto bounds = getLocalBounds();\r
 \r
-            for (auto &rc : rowComponents)\r
+            for (autorc : rowComponents)\r
                 rc->setBounds (bounds.removeFromTop (rc->rowUnits * rowHeight));\r
 \r
             auto* last = rowComponents[rowComponents.size() - 1];\r
@@ -1007,9 +1007,7 @@ private:
         void resized() override\r
         {\r
             auto columnWidth = getWidth();\r
-\r
             auto rowHeight = getHeight() / 6;\r
-\r
             auto bounds = getLocalBounds();\r
 \r
             getDeliveredNotificationsButton .setBounds (bounds.removeFromTop (rowHeight));\r
@@ -1020,7 +1018,7 @@ private:
 \r
             removeAllDeliveredNotifsButton  .setBounds (bounds.removeFromTop (rowHeight));\r
 \r
-          #if JUCE_IOS || JUCE_MAC\r
+           #if JUCE_IOS || JUCE_MAC\r
             getPendingNotificationsButton .setBounds (bounds.removeFromTop (rowHeight));\r
 \r
             rowBounds = bounds.removeFromTop (rowHeight);\r
@@ -1028,7 +1026,7 @@ private:
             pendingNotifIdentifier        .setBounds (rowBounds);\r
 \r
             removeAllPendingNotifsButton  .setBounds (bounds.removeFromTop (rowHeight));\r
-          #endif\r
+           #endif\r
         }\r
 \r
         TextButton getDeliveredNotificationsButton  { "Get Delivered Notifications" };\r
@@ -1046,11 +1044,11 @@ private:
         RemoteView()\r
         {\r
             addAndMakeVisible (getDeviceTokenButton);\r
-          #if JUCE_ANDROID\r
+           #if JUCE_ANDROID\r
             addAndMakeVisible (sendRemoteMessageButton);\r
             addAndMakeVisible (subscribeToSportsButton);\r
             addAndMakeVisible (unsubscribeFromSportsButton);\r
-          #endif\r
+           #endif\r
         }\r
 \r
         void resized()\r
@@ -1085,10 +1083,8 @@ private:
             if (! showedRemoteInstructions && newCurrentTabName == "Remote")\r
             {\r
                 PushNotificationsDemo::showRemoteInstructions();\r
-\r
                 showedRemoteInstructions = true;\r
             }\r
-\r
         }\r
 \r
     private:\r
@@ -1097,22 +1093,19 @@ private:
 \r
     static void showRemoteInstructions()\r
     {\r
-      #if JUCE_IOS || JUCE_MAC\r
+       #if JUCE_IOS || JUCE_MAC\r
         NativeMessageBox::showMessageBoxAsync (AlertWindow::InfoIcon,\r
                                                "Remote Notifications instructions",\r
                                                "In order to be able to test remote notifications "\r
                                                "ensure that the app is signed and that you register "\r
                                                "the bundle ID for remote notifications in "\r
                                                "Apple Developer Center.");\r
-      #endif\r
+       #endif\r
     }\r
 \r
     Label headerLabel { "headerLabel", "Push Notifications Demo" };\r
     ParamControls paramControls;\r
-    ParamsView paramsOneView;\r
-    ParamsView paramsTwoView;\r
-    ParamsView paramsThreeView;\r
-    ParamsView paramsFourView;\r
+    ParamsView paramsOneView, paramsTwoView, paramsThreeView, paramsFourView;\r
     AuxActionsView auxActionsView;\r
     TabbedComponent localNotificationsTabs { TabbedButtonBar::TabsAtTop };\r
     RemoteView remoteView;\r
diff --git a/examples/Utilities/SimpleFFTDemo.h b/examples/Utilities/SimpleFFTDemo.h
deleted file mode 100644 (file)
index 0d6b8ee..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*\r
-  ==============================================================================\r
-\r
-   This file is part of the JUCE examples.\r
-   Copyright (c) 2017 - ROLI Ltd.\r
-\r
-   The code included in this file is provided under the terms of the ISC license\r
-   http://www.isc.org/downloads/software-support-policy/isc-license. Permission\r
-   To use, copy, modify, and/or distribute this software for any purpose with or\r
-   without fee is hereby granted provided that the above copyright notice and\r
-   this permission notice appear in all copies.\r
-\r
-   THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES,\r
-   WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR\r
-   PURPOSE, ARE DISCLAIMED.\r
-\r
-  ==============================================================================\r
-*/\r
-\r
-/*******************************************************************************\r
- The block below describes the properties of this PIP. A PIP is a short snippet\r
- of code that can be read by the Projucer and used to generate a JUCE project.\r
-\r
- BEGIN_JUCE_PIP_METADATA\r
-\r
- name:             SimpleFFTDemo\r
- version:          1.0.0\r
- vendor:           juce\r
- website:          http://juce.com\r
- description:      Simple FFT application.\r
-\r
- dependencies:     juce_audio_basics, juce_audio_devices, juce_audio_formats,\r
-                   juce_audio_processors, juce_audio_utils, juce_core,\r
-                   juce_data_structures, juce_dsp, juce_events, juce_graphics,\r
-                   juce_gui_basics, juce_gui_extra\r
- exporters:        xcode_mac, vs2017\r
-\r
- type:             Component\r
- mainClass:        SimpleFFTDemo\r
-\r
- useLocalCopy:     1\r
-\r
- END_JUCE_PIP_METADATA\r
-\r
-*******************************************************************************/\r
-\r
-#pragma once\r
-\r
-\r
-//==============================================================================\r
-class SimpleFFTDemo   : public AudioAppComponent,\r
-                        private Timer\r
-{\r
-public:\r
-    SimpleFFTDemo()\r
-        : forwardFFT (fftOrder),\r
-          spectrogramImage (Image::RGB, 512, 512, true)\r
-    {\r
-        setOpaque (true);\r
-        setAudioChannels (2, 0);  // we want a couple of input channels but no outputs\r
-        startTimerHz (60);\r
-        setSize (700, 500);\r
-    }\r
-\r
-    ~SimpleFFTDemo()\r
-    {\r
-        shutdownAudio();\r
-    }\r
-\r
-    //==============================================================================\r
-    void prepareToPlay (int /*samplesPerBlockExpected*/, double /*newSampleRate*/) override\r
-    {\r
-        // (nothing to do here)\r
-    }\r
-\r
-    void releaseResources() override\r
-    {\r
-        // (nothing to do here)\r
-    }\r
-\r
-    void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override\r
-    {\r
-        if (bufferToFill.buffer->getNumChannels() > 0)\r
-        {\r
-            auto* channelData = bufferToFill.buffer->getWritePointer (0, bufferToFill.startSample);\r
-\r
-            for (auto i = 0; i < bufferToFill.numSamples; ++i)\r
-                pushNextSampleIntoFifo (channelData[i]);\r
-        }\r
-    }\r
-\r
-    //==============================================================================\r
-    void paint (Graphics& g) override\r
-    {\r
-        g.fillAll (Colours::black);\r
-\r
-        g.setOpacity (1.0f);\r
-        g.drawImage (spectrogramImage, getLocalBounds().toFloat());\r
-    }\r
-\r
-    void timerCallback() override\r
-    {\r
-        if (nextFFTBlockReady)\r
-        {\r
-            drawNextLineOfSpectrogram();\r
-            nextFFTBlockReady = false;\r
-            repaint();\r
-        }\r
-    }\r
-\r
-    void pushNextSampleIntoFifo (float sample) noexcept\r
-    {\r
-        // if the fifo contains enough data, set a flag to say\r
-        // that the next line should now be rendered..\r
-        if (fifoIndex == fftSize)\r
-        {\r
-            if (! nextFFTBlockReady)\r
-            {\r
-                zeromem (fftData, sizeof (fftData));\r
-                memcpy (fftData, fifo, sizeof (fifo));\r
-                nextFFTBlockReady = true;\r
-            }\r
-\r
-            fifoIndex = 0;\r
-        }\r
-\r
-        fifo[fifoIndex++] = sample;\r
-    }\r
-\r
-    void drawNextLineOfSpectrogram()\r
-    {\r
-        auto rightHandEdge = spectrogramImage.getWidth() - 1;\r
-        auto imageHeight   = spectrogramImage.getHeight();\r
-\r
-        // first, shuffle our image leftwards by 1 pixel..\r
-        spectrogramImage.moveImageSection (0, 0, 1, 0, rightHandEdge, imageHeight);\r
-\r
-        // then render our FFT data..\r
-        forwardFFT.performFrequencyOnlyForwardTransform (fftData);\r
-\r
-        // find the range of values produced, so we can scale our rendering to\r
-        // show up the detail clearly\r
-        auto maxLevel = FloatVectorOperations::findMinAndMax (fftData, fftSize / 2);\r
-\r
-        for (auto y = 1; y < imageHeight; ++y)\r
-        {\r
-            auto skewedProportionY = 1.0f - std::exp (std::log (y / (float) imageHeight) * 0.2f);\r
-            auto fftDataIndex = jlimit (0, fftSize / 2, (int) (skewedProportionY * fftSize / 2));\r
-            auto level = jmap (fftData[fftDataIndex], 0.0f, jmax (maxLevel.getEnd(), 1e-5f), 0.0f, 1.0f);\r
-\r
-            spectrogramImage.setPixelAt (rightHandEdge, y, Colour::fromHSV (level, 1.0f, level, 1.0f));\r
-        }\r
-    }\r
-\r
-    enum\r
-    {\r
-        fftOrder = 10,\r
-        fftSize  = 1 << fftOrder\r
-    };\r
-\r
-private:\r
-    dsp::FFT forwardFFT;\r
-    Image spectrogramImage;\r
-\r
-    float fifo [fftSize];\r
-    float fftData [2 * fftSize];\r
-    int fifoIndex = 0;\r
-    bool nextFFTBlockReady = false;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SimpleFFTDemo)\r
-};\r
index c85f80603ab189ac40b78206df444e2b90535bc8..7c6dfb88210222717aa91ef1e7bcc1e34ad8d904 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             SystemInfoDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Displays system information.\r
 \r
index b8de741c7ba8d2099d2a14547dd21fecc175d111..4f34e78eafd43fe7940bf093366e263d6f43170d 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             TimersAndEventsDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Application using timers and events.\r
 \r
index 6c2b82861468e710fa724eb2014bdd44a3d0ea62..e8e22601c64a064822e3e198614ba0656eb895e2 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             UnitTestsDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Performs unit tests.\r
 \r
index 1fb0b8229f21bfee5c5ffd6bb87be43764c10e43..4bef4120c920be783cd67ec7b69041fd560f34d8 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             ValueTreesDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Showcases value tree features.\r
 \r
index 9d30895be387d4b78595448cf5132207008527bf..0fc695f0b47d528e8e6bab7c9b1554dfa5a81085 100644 (file)
@@ -25,7 +25,7 @@
 \r
  name:             XMLandJSONDemo\r
  version:          1.0.0\r
- vendor:           juce\r
+ vendor:           JUCE\r
  website:          http://juce.com\r
  description:      Reads XML and JSON files.\r
 \r
index fb810cfd1af6a1a665b8e7e4918b45c1315b8013..f050db30549ade7be72b3a1b4e58d12f8d48125d 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 \r
 <JUCERPROJECT id="AKfc5m" name="AudioPerformanceTest" projectType="guiapp"\r
-              bundleIdentifier="com.juce.AudioPerformanceTest" jucerVersion="5.3.0"\r
+              bundleIdentifier="com.juce.AudioPerformanceTest" jucerVersion="5.3.1"\r
               displaySplashScreen="0" reportAppUsage="0" companyName="ROLI Ltd."\r
               companyCopyright="ROLI Ltd.">\r
   <MAINGROUP id="b1eVTe" name="AudioPerformanceTest">\r
index 1e1ee75ef5b7657ea3ab530dbb4b33a2cd25891f..1acb8f22b012e996575b1a14da2c24303f679c41 100644 (file)
@@ -122,6 +122,7 @@ add_library( ${BINARY_NAME}
     "../../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp"\r
     "../../../../../modules/juce_audio_devices/native/juce_ios_Audio.h"\r
     "../../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_linux_Bela.cpp"\r
     "../../../../../modules/juce_audio_devices/native/juce_linux_JackAudio.cpp"\r
     "../../../../../modules/juce_audio_devices/native/juce_linux_Midi.cpp"\r
     "../../../../../modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp"\r
@@ -304,6 +305,7 @@ add_library( ${BINARY_NAME}
     "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_VST3Common.h"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_VST3Headers.h"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp"\r
@@ -1061,6 +1063,8 @@ add_library( ${BINARY_NAME}
     "../../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"\r
     "../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp"\r
     "../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h"\r
     "../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp"\r
     "../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.h"\r
     "../../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp"\r
@@ -1285,6 +1289,7 @@ set_source_files_properties("../../../../../modules/juce_audio_devices/native/ju
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_ios_Audio.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_Bela.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_JackAudio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_Midi.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
@@ -1467,6 +1472,7 @@ set_source_files_properties("../../../../../modules/juce_audio_processors/format
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3Common.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3Headers.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
@@ -2224,6 +2230,8 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/properties/j
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
index 3707b70f3cac1e90f9e63b0e73ee181777775506..a0ce9c2df12f9acd0135edba8e88ef1cf1ff2fee 100644 (file)
@@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
 \r
 android {\r
     compileSdkVersion 23\r
-    buildToolsVersion "27.0.0"\r
+    buildToolsVersion "27.0.3"\r
     externalNativeBuild {\r
         cmake {\r
             path "CMakeLists.txt"\r
index a7e2360225a243c5e0287bc114163d463aec2c66..28e29b6460949599aa820b267bc0c030af62bfd6 100644 (file)
@@ -1238,7 +1238,10 @@ public class AudioPerformanceTest   extends Activity
 \r
         // Ensure that navigation/status bar visibility is correctly restored.\r
         for (int i = 0; i < viewHolder.getChildCount(); ++i)\r
-            ((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();\r
+        {\r
+            if (viewHolder.getChildAt (i) instanceof ComponentPeerView)\r
+                ((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();\r
+        }\r
     }\r
 \r
     @Override\r
@@ -1820,19 +1823,37 @@ public class AudioPerformanceTest   extends Activity
 \r
             private class TreeObserver implements ViewTreeObserver.OnGlobalLayoutListener\r
             {\r
+                TreeObserver()\r
+                {\r
+                    keyboardShown = false;\r
+                }\r
+\r
                 @Override\r
                 public void onGlobalLayout()\r
                 {\r
                     Rect r = new Rect();\r
 \r
-                    view.getWindowVisibleDisplayFrame(r);\r
+                    ViewGroup parentView = (ViewGroup) getParent();\r
+\r
+                    if (parentView == null)\r
+                        return;\r
 \r
-                    int diff = view.getHeight() - (r.bottom - r.top);\r
+                    parentView.getWindowVisibleDisplayFrame (r);\r
+\r
+                    int diff = parentView.getHeight() - (r.bottom - r.top);\r
 \r
                     // Arbitrary threshold, surely keyboard would take more than 20 pix.\r
-                    if (diff < 20)\r
+                    if (diff < 20 && keyboardShown)\r
+                    {\r
+                        keyboardShown = false;\r
                         handleKeyboardHidden (view.host);\r
+                    }\r
+\r
+                    if (! keyboardShown && diff > 20)\r
+                        keyboardShown = true;\r
                 };\r
+\r
+                private boolean keyboardShown;\r
             };\r
 \r
             private ComponentPeerView view;\r
index 07b77dd931f3c186956af07d08e7ae7478ad1a88..651d63db63bdd2bf53a574bdde786ac927b14169 100644 (file)
@@ -1,15 +1,16 @@
 buildscript {\r
    repositories {\r
-       jcenter()\r
        google()\r
+       jcenter()\r
    }\r
    dependencies {\r
-       classpath 'com.android.tools.build:gradle:3.0.1'\r
+       classpath 'com.android.tools.build:gradle:3.1.1'\r
    }\r
 }\r
 \r
 allprojects {\r
    repositories {\r
+       google()\r
        jcenter()\r
    }\r
 }\r
index 6654a817a24092a7793c22f24c55a1c02dfbc7d4..d384d28fd88d3528bda61f4e6d2103d0ce17e8fe 100644 (file)
@@ -1 +1 @@
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
\ No newline at end of file
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
\ No newline at end of file
index 8ae6fbc5d34c1d931ad9fd7741961a6ca1cda4ed..03ef95ed348478e69ba6401161afca4b27fda0a5 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
index 475051af63676ab49c26a816a6367bd7bc52ce07..c4b5c70370c3c14a4d3048def74b9a4f62070e02 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
index f0ecb1b1794570b421ba6b8d0576fdcc313bba21..109ec4a7722591d5b77d967201ef56379c87d354 100644 (file)
  //#define JUCE_JACK 0\r
 #endif\r
 \r
+#ifndef    JUCE_BELA\r
+ //#define JUCE_BELA 0\r
+#endif\r
+\r
 #ifndef    JUCE_USE_ANDROID_OBOE\r
  //#define JUCE_USE_ANDROID_OBOE 0\r
 #endif\r
index 42af1229c4c95df16a5d70c080577ed9676ed573..19fbee32daeec370da7e3d0e699dbdc75ad1e083 100644 (file)
@@ -2,11 +2,13 @@
 \r
 <JUCERPROJECT id="NTe0XB0ij" name="AudioPluginHost" projectType="guiapp" version="1.0.0"\r
               juceFolder="../../../juce" vstFolderMac="~/SDKs/vstsdk2.4" vstFolderPC="c:\SDKs\vstsdk2.4"\r
-              bundleIdentifier="com.roli.pluginhost" jucerVersion="5.3.0" companyName="ROLI Ltd."\r
-              displaySplashScreen="0" reportAppUsage="0" companyCopyright="ROLI Ltd.">\r
+              bundleIdentifier="com.roli.juce.pluginhost" jucerVersion="5.3.1"\r
+              companyName="ROLI Ltd." displaySplashScreen="0" reportAppUsage="0"\r
+              companyCopyright="ROLI Ltd.">\r
   <EXPORTFORMATS>\r
     <XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="" rtasFolder="~/SDKs/PT_80_SDK"\r
-               objCExtraSuffix="M73TRi" vst3Folder="" extraCompilerFlags="-Wall -Wshadow -Wstrict-aliasing -Wconversion -Wsign-compare -Woverloaded-virtual -Wextra-semi">\r
+               objCExtraSuffix="M73TRi" vst3Folder="" extraCompilerFlags="-Wall -Wshadow -Wstrict-aliasing -Wconversion -Wsign-compare -Woverloaded-virtual -Wextra-semi"\r
+               smallIcon="c97aUr" bigIcon="c97aUr">\r
       <CONFIGURATIONS>\r
         <CONFIGURATION name="Debug" isDebug="1" targetName="AudioPluginHost"/>\r
         <CONFIGURATION name="Release" isDebug="0" optimisation="2" targetName="AudioPluginHost"/>\r
@@ -28,7 +30,8 @@
         <MODULEPATH id="juce_audio_basics" path="../../modules"/>\r
       </MODULEPATHS>\r
     </XCODE_MAC>\r
-    <LINUX_MAKE targetFolder="Builds/LinuxMakefile" vstFolder="" vst3Folder="">\r
+    <LINUX_MAKE targetFolder="Builds/LinuxMakefile" vstFolder="" vst3Folder=""\r
+                smallIcon="c97aUr" bigIcon="c97aUr">\r
       <CONFIGURATIONS>\r
         <CONFIGURATION name="Debug" isDebug="1" targetName="AudioPluginHost" libraryPath="/usr/X11R6/lib/"/>\r
         <CONFIGURATION name="Release" isDebug="0" optimisation="2" targetName="AudioPluginHost"\r
@@ -51,7 +54,8 @@
         <MODULEPATH id="juce_audio_basics" path="../../modules"/>\r
       </MODULEPATHS>\r
     </LINUX_MAKE>\r
-    <VS2013 targetFolder="Builds/VisualStudio2013" vstFolder="" vst3Folder="">\r
+    <VS2013 targetFolder="Builds/VisualStudio2013" vstFolder="" vst3Folder=""\r
+            smallIcon="c97aUr" bigIcon="c97aUr">\r
       <CONFIGURATIONS>\r
         <CONFIGURATION name="Debug" winArchitecture="32-bit" isDebug="1" optimisation="1"\r
                        targetName="AudioPluginHost"/>\r
@@ -75,7 +79,8 @@
         <MODULEPATH id="juce_audio_basics" path="../../modules"/>\r
       </MODULEPATHS>\r
     </VS2013>\r
-    <VS2015 targetFolder="Builds/VisualStudio2015" vstFolder="" vst3Folder="">\r
+    <VS2015 targetFolder="Builds/VisualStudio2015" vstFolder="" vst3Folder=""\r
+            smallIcon="c97aUr" bigIcon="c97aUr">\r
       <CONFIGURATIONS>\r
         <CONFIGURATION name="Debug" isDebug="1" targetName="AudioPluginHost"/>\r
         <CONFIGURATION name="Release" isDebug="0" targetName="AudioPluginHost" debugInformationFormat="ProgramDatabase"/>\r
         <MODULEPATH id="juce_audio_basics" path="../../modules"/>\r
       </MODULEPATHS>\r
     </VS2015>\r
-    <VS2017 targetFolder="Builds/VisualStudio2017" vst3Folder="">\r
+    <VS2017 targetFolder="Builds/VisualStudio2017" vst3Folder="" smallIcon="c97aUr"\r
+            bigIcon="c97aUr">\r
       <CONFIGURATIONS>\r
         <CONFIGURATION name="Debug" isDebug="1" targetName="AudioPluginHost"/>\r
         <CONFIGURATION name="Release" isDebug="0" targetName="AudioPluginHost" debugInformationFormat="ProgramDatabase"/>\r
         <MODULEPATH id="juce_audio_basics" path="../../modules"/>\r
       </MODULEPATHS>\r
     </VS2017>\r
+    <XCODE_IPHONE targetFolder="Builds/iOS" iosScreenOrientation="portraitlandscape"\r
+                  iPadScreenOrientation="portraitlandscape" iosDeviceFamily="1,2"\r
+                  vst3Folder="" microphonePermissionNeeded="1" iosBackgroundAudio="1"\r
+                  iosBackgroundBle="1" smallIcon="c97aUr" bigIcon="c97aUr">\r
+      <CONFIGURATIONS>\r
+        <CONFIGURATION name="Debug" enablePluginBinaryCopyStep="1" isDebug="1" optimisation="1"\r
+                       linkTimeOptimisation="0" targetName="Plugin Host"/>\r
+        <CONFIGURATION name="Release" enablePluginBinaryCopyStep="1" isDebug="0" optimisation="3"\r
+                       linkTimeOptimisation="1" targetName="Plugin Host"/>\r
+      </CONFIGURATIONS>\r
+      <MODULEPATHS>\r
+        <MODULEPATH id="juce_video" path="../../modules"/>\r
+        <MODULEPATH id="juce_opengl" path="../../modules"/>\r
+        <MODULEPATH id="juce_gui_extra" path="../../modules"/>\r
+        <MODULEPATH id="juce_gui_basics" path="../../modules"/>\r
+        <MODULEPATH id="juce_graphics" path="../../modules"/>\r
+        <MODULEPATH id="juce_events" path="../../modules"/>\r
+        <MODULEPATH id="juce_data_structures" path="../../modules"/>\r
+        <MODULEPATH id="juce_cryptography" path="../../modules"/>\r
+        <MODULEPATH id="juce_core" path="../../modules"/>\r
+        <MODULEPATH id="juce_audio_utils" path="../../modules"/>\r
+        <MODULEPATH id="juce_audio_processors" path="../../modules"/>\r
+        <MODULEPATH id="juce_audio_formats" path="../../modules"/>\r
+        <MODULEPATH id="juce_audio_devices" path="../../modules"/>\r
+        <MODULEPATH id="juce_audio_basics" path="../../modules"/>\r
+      </MODULEPATHS>\r
+    </XCODE_IPHONE>\r
+    <ANDROIDSTUDIO targetFolder="Builds/Android" androidSDKPath="" androidNDKPath=""\r
+                   androidMinimumSDK="23" androidInternetNeeded="1" microphonePermissionNeeded="1"\r
+                   androidBluetoothNeeded="1" smallIcon="c97aUr" bigIcon="c97aUr">\r
+      <CONFIGURATIONS>\r
+        <CONFIGURATION name="Debug" androidArchitectures="armeabi x86" isDebug="1" optimisation="1"\r
+                       linkTimeOptimisation="0" targetName="Plugin Host"/>\r
+        <CONFIGURATION name="Release" androidArchitectures="" isDebug="0" optimisation="3"\r
+                       linkTimeOptimisation="1" targetName="Plugin Host"/>\r
+      </CONFIGURATIONS>\r
+      <MODULEPATHS>\r
+        <MODULEPATH id="juce_video" path="../../modules"/>\r
+        <MODULEPATH id="juce_opengl" path="../../modules"/>\r
+        <MODULEPATH id="juce_gui_extra" path="../../modules"/>\r
+        <MODULEPATH id="juce_gui_basics" path="../../modules"/>\r
+        <MODULEPATH id="juce_graphics" path="../../modules"/>\r
+        <MODULEPATH id="juce_events" path="../../modules"/>\r
+        <MODULEPATH id="juce_data_structures" path="../../modules"/>\r
+        <MODULEPATH id="juce_cryptography" path="../../modules"/>\r
+        <MODULEPATH id="juce_core" path="../../modules"/>\r
+        <MODULEPATH id="juce_audio_utils" path="../../modules"/>\r
+        <MODULEPATH id="juce_audio_processors" path="../../modules"/>\r
+        <MODULEPATH id="juce_audio_formats" path="../../modules"/>\r
+        <MODULEPATH id="juce_audio_devices" path="../../modules"/>\r
+        <MODULEPATH id="juce_audio_basics" path="../../modules"/>\r
+      </MODULEPATHS>\r
+    </ANDROIDSTUDIO>\r
   </EXPORTFORMATS>\r
   <MAINGROUP id="YdWL7hi7p" name="AudioPluginHost">\r
-    <FILE id="8tLeuntR4" name="FilterGraph.cpp" compile="1" resource="0"\r
-          file="Source/FilterGraph.cpp"/>\r
-    <FILE id="auGSxnlTU" name="FilterGraph.h" compile="0" resource="0"\r
-          file="Source/FilterGraph.h"/>\r
-    <FILE id="cnfPX5" name="FilterIOConfiguration.cpp" compile="1" resource="0"\r
-          file="Source/FilterIOConfiguration.cpp"/>\r
-    <FILE id="ZVUq7Q" name="FilterIOConfiguration.h" compile="0" resource="0"\r
-          file="Source/FilterIOConfiguration.h"/>\r
-    <FILE id="2b09bSUt" name="GraphEditorPanel.cpp" compile="1" resource="0"\r
-          file="Source/GraphEditorPanel.cpp"/>\r
-    <FILE id="sj8Yug8cu" name="GraphEditorPanel.h" compile="0" resource="0"\r
-          file="Source/GraphEditorPanel.h"/>\r
-    <FILE id="nehnGjkrX" name="HostStartup.cpp" compile="1" resource="0"\r
-          file="Source/HostStartup.cpp"/>\r
-    <FILE id="J6HWWSQP1" name="InternalFilters.cpp" compile="1" resource="0"\r
-          file="Source/InternalFilters.cpp"/>\r
-    <FILE id="AplCcJ0La" name="InternalFilters.h" compile="0" resource="0"\r
-          file="Source/InternalFilters.h"/>\r
-    <FILE id="mFVSjbHfN" name="MainHostWindow.cpp" compile="1" resource="0"\r
-          file="Source/MainHostWindow.cpp"/>\r
-    <FILE id="h1kpxyzHi" name="MainHostWindow.h" compile="0" resource="0"\r
-          file="Source/MainHostWindow.h"/>\r
-    <FILE id="ZwQDmm" name="PluginWindow.h" compile="0" resource="0" file="Source/PluginWindow.h"/>\r
+    <GROUP id="{CFED5B3D-D1D8-0F3F-4D67-B2A810D057EF}" name="Source">\r
+      <GROUP id="{AE20356E-1F78-F99D-7D44-08529665AEDA}" name="Filters">\r
+        <FILE id="CogQ5Q" name="FilterGraph.cpp" compile="1" resource="0" file="Source/Filters/FilterGraph.cpp"/>\r
+        <FILE id="pfZWFw" name="FilterGraph.h" compile="0" resource="0" file="Source/Filters/FilterGraph.h"/>\r
+        <FILE id="BltUzI" name="FilterIOConfiguration.cpp" compile="1" resource="0"\r
+              file="Source/Filters/FilterIOConfiguration.cpp"/>\r
+        <FILE id="r9SuL8" name="FilterIOConfiguration.h" compile="0" resource="0"\r
+              file="Source/Filters/FilterIOConfiguration.h"/>\r
+        <FILE id="UcOOog" name="InternalFilters.cpp" compile="1" resource="0"\r
+              file="Source/Filters/InternalFilters.cpp"/>\r
+        <FILE id="Bll6sn" name="InternalFilters.h" compile="0" resource="0"\r
+              file="Source/Filters/InternalFilters.h"/>\r
+      </GROUP>\r
+      <GROUP id="{D892BFB2-FE85-B70F-10D3-450F407E2B3D}" name="UI">\r
+        <FILE id="wPgLS9" name="GraphEditorPanel.cpp" compile="1" resource="0"\r
+              file="Source/UI/GraphEditorPanel.cpp"/>\r
+        <FILE id="BDMvfT" name="GraphEditorPanel.h" compile="0" resource="0"\r
+              file="Source/UI/GraphEditorPanel.h"/>\r
+        <FILE id="AVGs2y" name="MainHostWindow.cpp" compile="1" resource="0"\r
+              file="Source/UI/MainHostWindow.cpp"/>\r
+        <FILE id="Ia6Vec" name="MainHostWindow.h" compile="0" resource="0"\r
+              file="Source/UI/MainHostWindow.h"/>\r
+        <FILE id="ygZQZ1" name="PluginWindow.h" compile="0" resource="0" file="Source/UI/PluginWindow.h"/>\r
+      </GROUP>\r
+      <FILE id="OmIhwQ" name="HostStartup.cpp" compile="1" resource="0" file="Source/HostStartup.cpp"/>\r
+      <FILE id="c97aUr" name="JUCEAppIcon.png" compile="0" resource="1" file="Source/JUCEAppIcon.png"/>\r
+    </GROUP>\r
   </MAINGROUP>\r
-  <JUCEOPTIONS JUCE_WASAPI="1" JUCE_DIRECTSOUND="1" JUCE_ALSA="1" JUCE_USE_FLAC="0"\r
-               JUCE_USE_OGGVORBIS="0" JUCE_USE_CDBURNER="0" JUCE_USE_CDREADER="0"\r
-               JUCE_USE_CAMERA="0" JUCE_PLUGINHOST_VST="1" JUCE_PLUGINHOST_AU="1"\r
-               JUCE_WEB_BROWSER="0" JUCE_PLUGINHOST_VST3="1"/>\r
+  <JUCEOPTIONS JUCE_WASAPI="1" JUCE_DIRECTSOUND="1" JUCE_ALSA="1" JUCE_QUICKTIME="disabled"\r
+               JUCE_USE_FLAC="0" JUCE_USE_OGGVORBIS="0" JUCE_USE_CDBURNER="0"\r
+               JUCE_USE_CDREADER="0" JUCE_USE_CAMERA="0" JUCE_PLUGINHOST_VST="1"\r
+               JUCE_PLUGINHOST_AU="1" JUCE_WEB_BROWSER="0" JUCE_PLUGINHOST_VST3="1"/>\r
   <MODULES>\r
     <MODULE id="juce_audio_basics" showAllCode="1"/>\r
     <MODULE id="juce_audio_devices" showAllCode="1"/>\r
diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
new file mode 100644 (file)
index 0000000..11a1f09
--- /dev/null
@@ -0,0 +1,2516 @@
+# Automatically generated makefile, created by the Projucer\r
+# Don't edit this file! Your changes will be overwritten when you re-save the Projucer project!\r
+\r
+cmake_minimum_required(VERSION 3.4.1)\r
+\r
+SET(BINARY_NAME "juce_jni")\r
+\r
+add_library("cpufeatures" STATIC "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c")\r
+set_source_files_properties("${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c" PROPERTIES COMPILE_FLAGS "-Wno-sign-conversion -Wno-gnu-statement-expression")\r
+\r
+add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_ANDROID_ACTIVITY_CLASSNAME=com_roli_juce_pluginhost_AudioPluginHost" "-DJUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/roli/juce/pluginhost/AudioPluginHost\"" "-DJUCE_ANDROID_SHARING_CONTENT_PROVIDER_CLASSNAME=com_roli_juce_pluginhost_SharingContentProvider" "-DJUCE_ANDROID_SHARING_CONTENT_PROVIDER_CLASSPATH=\"com/roli/juce/pluginhost/SharingContentProvider\"" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000")\r
+\r
+include_directories( AFTER\r
+    "../../../JuceLibraryCode"\r
+    "../../../../../modules"\r
+    "${ANDROID_NDK}/sources/android/cpufeatures"\r
+)\r
+\r
+enable_language(ASM)\r
+\r
+IF(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG")\r
+    add_definitions("-DDEBUG=1" "-D_DEBUG=1")\r
+ELSEIF(JUCE_BUILD_CONFIGURATION MATCHES "RELEASE")\r
+    add_definitions("-DNDEBUG=1")\r
+    if(NOT (ANDROID_ABI STREQUAL "mips" OR ANDROID_ABI STREQUAL "mips64"))\r
+        SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -flto")\r
+        SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto")\r
+        SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -flto")\r
+    ENDIF(NOT (ANDROID_ABI STREQUAL "mips" OR ANDROID_ABI STREQUAL "mips64"))\r
+ELSE(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG")\r
+    MESSAGE( FATAL_ERROR "No matching build-configuration found." )\r
+ENDIF(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG")\r
+\r
+add_library( ${BINARY_NAME}\r
+\r
+    SHARED\r
+\r
+    "../../../Source/Filters/FilterGraph.cpp"\r
+    "../../../Source/Filters/FilterGraph.h"\r
+    "../../../Source/Filters/FilterIOConfiguration.cpp"\r
+    "../../../Source/Filters/FilterIOConfiguration.h"\r
+    "../../../Source/Filters/InternalFilters.cpp"\r
+    "../../../Source/Filters/InternalFilters.h"\r
+    "../../../Source/UI/GraphEditorPanel.cpp"\r
+    "../../../Source/UI/GraphEditorPanel.h"\r
+    "../../../Source/UI/MainHostWindow.cpp"\r
+    "../../../Source/UI/MainHostWindow.h"\r
+    "../../../Source/UI/PluginWindow.h"\r
+    "../../../Source/HostStartup.cpp"\r
+    "../../../Source/JUCEAppIcon.png"\r
+    "../../../../../modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h"\r
+    "../../../../../modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp"\r
+    "../../../../../modules/juce_audio_basics/buffers/juce_AudioChannelSet.h"\r
+    "../../../../../modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp"\r
+    "../../../../../modules/juce_audio_basics/buffers/juce_AudioDataConverters.h"\r
+    "../../../../../modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h"\r
+    "../../../../../modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp"\r
+    "../../../../../modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h"\r
+    "../../../../../modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp"\r
+    "../../../../../modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.h"\r
+    "../../../../../modules/juce_audio_basics/effects/juce_Decibels.h"\r
+    "../../../../../modules/juce_audio_basics/effects/juce_IIRFilter.cpp"\r
+    "../../../../../modules/juce_audio_basics/effects/juce_IIRFilter.h"\r
+    "../../../../../modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp"\r
+    "../../../../../modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h"\r
+    "../../../../../modules/juce_audio_basics/effects/juce_LinearSmoothedValue.h"\r
+    "../../../../../modules/juce_audio_basics/effects/juce_Reverb.h"\r
+    "../../../../../modules/juce_audio_basics/midi/juce_MidiBuffer.cpp"\r
+    "../../../../../modules/juce_audio_basics/midi/juce_MidiBuffer.h"\r
+    "../../../../../modules/juce_audio_basics/midi/juce_MidiFile.cpp"\r
+    "../../../../../modules/juce_audio_basics/midi/juce_MidiFile.h"\r
+    "../../../../../modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp"\r
+    "../../../../../modules/juce_audio_basics/midi/juce_MidiKeyboardState.h"\r
+    "../../../../../modules/juce_audio_basics/midi/juce_MidiMessage.cpp"\r
+    "../../../../../modules/juce_audio_basics/midi/juce_MidiMessage.h"\r
+    "../../../../../modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp"\r
+    "../../../../../modules/juce_audio_basics/midi/juce_MidiMessageSequence.h"\r
+    "../../../../../modules/juce_audio_basics/midi/juce_MidiRPN.cpp"\r
+    "../../../../../modules/juce_audio_basics/midi/juce_MidiRPN.h"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPEInstrument.h"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPEMessages.cpp"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPEMessages.h"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPENote.cpp"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPENote.h"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiser.cpp"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiser.h"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.cpp"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPEUtils.cpp"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPEUtils.h"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPEValue.cpp"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPEValue.h"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp"\r
+    "../../../../../modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h"\r
+    "../../../../../modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_AudioSource.h"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_BufferingAudioSource.h"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_MemoryAudioSource.h"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_MixerAudioSource.h"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_PositionableAudioSource.h"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_ReverbAudioSource.h"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp"\r
+    "../../../../../modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h"\r
+    "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp"\r
+    "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h"\r
+    "../../../../../modules/juce_audio_basics/juce_audio_basics.cpp"\r
+    "../../../../../modules/juce_audio_basics/juce_audio_basics.mm"\r
+    "../../../../../modules/juce_audio_basics/juce_audio_basics.h"\r
+    "../../../../../modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp"\r
+    "../../../../../modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h"\r
+    "../../../../../modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp"\r
+    "../../../../../modules/juce_audio_devices/audio_io/juce_AudioIODevice.h"\r
+    "../../../../../modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp"\r
+    "../../../../../modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h"\r
+    "../../../../../modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h"\r
+    "../../../../../modules/juce_audio_devices/midi_io/juce_MidiInput.h"\r
+    "../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp"\r
+    "../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h"\r
+    "../../../../../modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp"\r
+    "../../../../../modules/juce_audio_devices/midi_io/juce_MidiOutput.h"\r
+    "../../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_android_Oboe.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_android_OpenSL.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_ios_Audio.h"\r
+    "../../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_linux_Bela.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_linux_JackAudio.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_linux_Midi.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_MidiDataConcatenator.h"\r
+    "../../../../../modules/juce_audio_devices/native/juce_win32_ASIO.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_win32_DirectSound.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_win32_Midi.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_win32_WASAPI.cpp"\r
+    "../../../../../modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp"\r
+    "../../../../../modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h"\r
+    "../../../../../modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp"\r
+    "../../../../../modules/juce_audio_devices/sources/juce_AudioTransportSource.h"\r
+    "../../../../../modules/juce_audio_devices/juce_audio_devices.cpp"\r
+    "../../../../../modules/juce_audio_devices/juce_audio_devices.mm"\r
+    "../../../../../modules/juce_audio_devices/juce_audio_devices.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/cpu.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/crc.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/fixed.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/float.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/format.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/cpu.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/crc.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/fixed.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/float.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/format.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/md5.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/memory.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder_framing.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/window_flac.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/all.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/alloc.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/assert.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/callback.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/compat.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/endswap.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/export.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/Flac Licence.txt"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/format.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/metadata.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/ordinals.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/flac/win_utf8_io.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_51.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_stereo.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/floor/floor_books.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/uncoupled/res_books_uncoupled.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/floor_all.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_8.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_11.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_16.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_44.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_8.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_16.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44p51.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44u.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_8.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_11.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_16.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_22.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_32.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44p51.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44u.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_X.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/analysis.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/backends.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/block.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codec_internal.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor0.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor1.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/highlevel.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/info.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup_data.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mapping0.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/masking.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/misc.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/res0.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/scales.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/sharedbook.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/synthesis.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/bitwise.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/codec.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/config_types.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/framing.c"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/Ogg Vorbis Licence.txt"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/ogg.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/os_types.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/vorbisenc.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/oggvorbis/vorbisfile.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_WavAudioFormat.h"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp"\r
+    "../../../../../modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h"\r
+    "../../../../../modules/juce_audio_formats/format/juce_AudioFormat.cpp"\r
+    "../../../../../modules/juce_audio_formats/format/juce_AudioFormat.h"\r
+    "../../../../../modules/juce_audio_formats/format/juce_AudioFormatManager.cpp"\r
+    "../../../../../modules/juce_audio_formats/format/juce_AudioFormatManager.h"\r
+    "../../../../../modules/juce_audio_formats/format/juce_AudioFormatReader.cpp"\r
+    "../../../../../modules/juce_audio_formats/format/juce_AudioFormatReader.h"\r
+    "../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp"\r
+    "../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"\r
+    "../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"\r
+    "../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"\r
+    "../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"\r
+    "../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"\r
+    "../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"\r
+    "../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h"\r
+    "../../../../../modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h"\r
+    "../../../../../modules/juce_audio_formats/sampler/juce_Sampler.cpp"\r
+    "../../../../../modules/juce_audio_formats/sampler/juce_Sampler.h"\r
+    "../../../../../modules/juce_audio_formats/juce_audio_formats.cpp"\r
+    "../../../../../modules/juce_audio_formats/juce_audio_formats.mm"\r
+    "../../../../../modules/juce_audio_formats/juce_audio_formats.h"\r
+    "../../../../../modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp"\r
+    "../../../../../modules/juce_audio_processors/format/juce_AudioPluginFormat.h"\r
+    "../../../../../modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp"\r
+    "../../../../../modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_AU_Shared.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_VST3Common.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_VST3Headers.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_VSTCommon.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_VSTInterface.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_AudioPluginInstance.cpp"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_AudioPluginInstance.h"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.cpp"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.h"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_PluginDescription.cpp"\r
+    "../../../../../modules/juce_audio_processors/processors/juce_PluginDescription.h"\r
+    "../../../../../modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp"\r
+    "../../../../../modules/juce_audio_processors/scanning/juce_KnownPluginList.h"\r
+    "../../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp"\r
+    "../../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h"\r
+    "../../../../../modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp"\r
+    "../../../../../modules/juce_audio_processors/scanning/juce_PluginListComponent.h"\r
+    "../../../../../modules/juce_audio_processors/utilities/juce_AudioParameterBool.h"\r
+    "../../../../../modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h"\r
+    "../../../../../modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h"\r
+    "../../../../../modules/juce_audio_processors/utilities/juce_AudioParameterInt.h"\r
+    "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp"\r
+    "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h"\r
+    "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp"\r
+    "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h"\r
+    "../../../../../modules/juce_audio_processors/juce_audio_processors.cpp"\r
+    "../../../../../modules/juce_audio_processors/juce_audio_processors.mm"\r
+    "../../../../../modules/juce_audio_processors/juce_audio_processors.h"\r
+    "../../../../../modules/juce_audio_utils/audio_cd/juce_AudioCDBurner.h"\r
+    "../../../../../modules/juce_audio_utils/audio_cd/juce_AudioCDReader.cpp"\r
+    "../../../../../modules/juce_audio_utils/audio_cd/juce_AudioCDReader.h"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_AudioAppComponent.cpp"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_AudioAppComponent.h"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.h"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_AudioThumbnail.h"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_AudioThumbnailBase.h"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_AudioThumbnailCache.h"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.cpp"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.h"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_BluetoothMidiDevicePairingDialogue.h"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp"\r
+    "../../../../../modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h"\r
+    "../../../../../modules/juce_audio_utils/native/juce_android_BluetoothMidiDevicePairingDialogue.cpp"\r
+    "../../../../../modules/juce_audio_utils/native/juce_ios_BluetoothMidiDevicePairingDialogue.mm"\r
+    "../../../../../modules/juce_audio_utils/native/juce_linux_AudioCDReader.cpp"\r
+    "../../../../../modules/juce_audio_utils/native/juce_linux_BluetoothMidiDevicePairingDialogue.cpp"\r
+    "../../../../../modules/juce_audio_utils/native/juce_mac_AudioCDBurner.mm"\r
+    "../../../../../modules/juce_audio_utils/native/juce_mac_AudioCDReader.mm"\r
+    "../../../../../modules/juce_audio_utils/native/juce_mac_BluetoothMidiDevicePairingDialogue.mm"\r
+    "../../../../../modules/juce_audio_utils/native/juce_win_BluetoothMidiDevicePairingDialogue.cpp"\r
+    "../../../../../modules/juce_audio_utils/native/juce_win32_AudioCDBurner.cpp"\r
+    "../../../../../modules/juce_audio_utils/native/juce_win32_AudioCDReader.cpp"\r
+    "../../../../../modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp"\r
+    "../../../../../modules/juce_audio_utils/players/juce_AudioProcessorPlayer.h"\r
+    "../../../../../modules/juce_audio_utils/players/juce_SoundPlayer.cpp"\r
+    "../../../../../modules/juce_audio_utils/players/juce_SoundPlayer.h"\r
+    "../../../../../modules/juce_audio_utils/juce_audio_utils.cpp"\r
+    "../../../../../modules/juce_audio_utils/juce_audio_utils.mm"\r
+    "../../../../../modules/juce_audio_utils/juce_audio_utils.h"\r
+    "../../../../../modules/juce_core/containers/juce_AbstractFifo.cpp"\r
+    "../../../../../modules/juce_core/containers/juce_AbstractFifo.h"\r
+    "../../../../../modules/juce_core/containers/juce_Array.h"\r
+    "../../../../../modules/juce_core/containers/juce_ArrayAllocationBase.h"\r
+    "../../../../../modules/juce_core/containers/juce_DynamicObject.cpp"\r
+    "../../../../../modules/juce_core/containers/juce_DynamicObject.h"\r
+    "../../../../../modules/juce_core/containers/juce_ElementComparator.h"\r
+    "../../../../../modules/juce_core/containers/juce_HashMap.h"\r
+    "../../../../../modules/juce_core/containers/juce_HashMap_test.cpp"\r
+    "../../../../../modules/juce_core/containers/juce_LinkedListPointer.h"\r
+    "../../../../../modules/juce_core/containers/juce_ListenerList.h"\r
+    "../../../../../modules/juce_core/containers/juce_NamedValueSet.cpp"\r
+    "../../../../../modules/juce_core/containers/juce_NamedValueSet.h"\r
+    "../../../../../modules/juce_core/containers/juce_OwnedArray.h"\r
+    "../../../../../modules/juce_core/containers/juce_PropertySet.cpp"\r
+    "../../../../../modules/juce_core/containers/juce_PropertySet.h"\r
+    "../../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h"\r
+    "../../../../../modules/juce_core/containers/juce_ScopedValueSetter.h"\r
+    "../../../../../modules/juce_core/containers/juce_SortedSet.h"\r
+    "../../../../../modules/juce_core/containers/juce_SparseSet.h"\r
+    "../../../../../modules/juce_core/containers/juce_Variant.cpp"\r
+    "../../../../../modules/juce_core/containers/juce_Variant.h"\r
+    "../../../../../modules/juce_core/files/juce_DirectoryIterator.cpp"\r
+    "../../../../../modules/juce_core/files/juce_DirectoryIterator.h"\r
+    "../../../../../modules/juce_core/files/juce_File.cpp"\r
+    "../../../../../modules/juce_core/files/juce_File.h"\r
+    "../../../../../modules/juce_core/files/juce_FileFilter.cpp"\r
+    "../../../../../modules/juce_core/files/juce_FileFilter.h"\r
+    "../../../../../modules/juce_core/files/juce_FileInputStream.cpp"\r
+    "../../../../../modules/juce_core/files/juce_FileInputStream.h"\r
+    "../../../../../modules/juce_core/files/juce_FileOutputStream.cpp"\r
+    "../../../../../modules/juce_core/files/juce_FileOutputStream.h"\r
+    "../../../../../modules/juce_core/files/juce_FileSearchPath.cpp"\r
+    "../../../../../modules/juce_core/files/juce_FileSearchPath.h"\r
+    "../../../../../modules/juce_core/files/juce_MemoryMappedFile.h"\r
+    "../../../../../modules/juce_core/files/juce_TemporaryFile.cpp"\r
+    "../../../../../modules/juce_core/files/juce_TemporaryFile.h"\r
+    "../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp"\r
+    "../../../../../modules/juce_core/files/juce_WildcardFileFilter.h"\r
+    "../../../../../modules/juce_core/javascript/juce_Javascript.cpp"\r
+    "../../../../../modules/juce_core/javascript/juce_Javascript.h"\r
+    "../../../../../modules/juce_core/javascript/juce_JSON.cpp"\r
+    "../../../../../modules/juce_core/javascript/juce_JSON.h"\r
+    "../../../../../modules/juce_core/logging/juce_FileLogger.cpp"\r
+    "../../../../../modules/juce_core/logging/juce_FileLogger.h"\r
+    "../../../../../modules/juce_core/logging/juce_Logger.cpp"\r
+    "../../../../../modules/juce_core/logging/juce_Logger.h"\r
+    "../../../../../modules/juce_core/maths/juce_BigInteger.cpp"\r
+    "../../../../../modules/juce_core/maths/juce_BigInteger.h"\r
+    "../../../../../modules/juce_core/maths/juce_Expression.cpp"\r
+    "../../../../../modules/juce_core/maths/juce_Expression.h"\r
+    "../../../../../modules/juce_core/maths/juce_MathsFunctions.h"\r
+    "../../../../../modules/juce_core/maths/juce_NormalisableRange.h"\r
+    "../../../../../modules/juce_core/maths/juce_Random.cpp"\r
+    "../../../../../modules/juce_core/maths/juce_Random.h"\r
+    "../../../../../modules/juce_core/maths/juce_Range.h"\r
+    "../../../../../modules/juce_core/maths/juce_StatisticsAccumulator.h"\r
+    "../../../../../modules/juce_core/memory/juce_Atomic.h"\r
+    "../../../../../modules/juce_core/memory/juce_ByteOrder.h"\r
+    "../../../../../modules/juce_core/memory/juce_ContainerDeletePolicy.h"\r
+    "../../../../../modules/juce_core/memory/juce_HeapBlock.h"\r
+    "../../../../../modules/juce_core/memory/juce_LeakedObjectDetector.h"\r
+    "../../../../../modules/juce_core/memory/juce_Memory.h"\r
+    "../../../../../modules/juce_core/memory/juce_MemoryBlock.cpp"\r
+    "../../../../../modules/juce_core/memory/juce_MemoryBlock.h"\r
+    "../../../../../modules/juce_core/memory/juce_OptionalScopedPointer.h"\r
+    "../../../../../modules/juce_core/memory/juce_ReferenceCountedObject.h"\r
+    "../../../../../modules/juce_core/memory/juce_ScopedPointer.h"\r
+    "../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h"\r
+    "../../../../../modules/juce_core/memory/juce_Singleton.h"\r
+    "../../../../../modules/juce_core/memory/juce_WeakReference.h"\r
+    "../../../../../modules/juce_core/misc/juce_Result.cpp"\r
+    "../../../../../modules/juce_core/misc/juce_Result.h"\r
+    "../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"\r
+    "../../../../../modules/juce_core/misc/juce_RuntimePermissions.h"\r
+    "../../../../../modules/juce_core/misc/juce_StdFunctionCompat.cpp"\r
+    "../../../../../modules/juce_core/misc/juce_StdFunctionCompat.h"\r
+    "../../../../../modules/juce_core/misc/juce_Uuid.cpp"\r
+    "../../../../../modules/juce_core/misc/juce_Uuid.h"\r
+    "../../../../../modules/juce_core/misc/juce_WindowsRegistry.h"\r
+    "../../../../../modules/juce_core/native/juce_android_Files.cpp"\r
+    "../../../../../modules/juce_core/native/juce_android_JNIHelpers.h"\r
+    "../../../../../modules/juce_core/native/juce_android_Misc.cpp"\r
+    "../../../../../modules/juce_core/native/juce_android_Network.cpp"\r
+    "../../../../../modules/juce_core/native/juce_android_RuntimePermissions.cpp"\r
+    "../../../../../modules/juce_core/native/juce_android_SystemStats.cpp"\r
+    "../../../../../modules/juce_core/native/juce_android_Threads.cpp"\r
+    "../../../../../modules/juce_core/native/juce_BasicNativeHeaders.h"\r
+    "../../../../../modules/juce_core/native/juce_curl_Network.cpp"\r
+    "../../../../../modules/juce_core/native/juce_linux_CommonFile.cpp"\r
+    "../../../../../modules/juce_core/native/juce_linux_Files.cpp"\r
+    "../../../../../modules/juce_core/native/juce_linux_Network.cpp"\r
+    "../../../../../modules/juce_core/native/juce_linux_SystemStats.cpp"\r
+    "../../../../../modules/juce_core/native/juce_linux_Threads.cpp"\r
+    "../../../../../modules/juce_core/native/juce_mac_ClangBugWorkaround.h"\r
+    "../../../../../modules/juce_core/native/juce_mac_Files.mm"\r
+    "../../../../../modules/juce_core/native/juce_mac_Network.mm"\r
+    "../../../../../modules/juce_core/native/juce_mac_Strings.mm"\r
+    "../../../../../modules/juce_core/native/juce_mac_SystemStats.mm"\r
+    "../../../../../modules/juce_core/native/juce_mac_Threads.mm"\r
+    "../../../../../modules/juce_core/native/juce_osx_ObjCHelpers.h"\r
+    "../../../../../modules/juce_core/native/juce_posix_NamedPipe.cpp"\r
+    "../../../../../modules/juce_core/native/juce_posix_SharedCode.h"\r
+    "../../../../../modules/juce_core/native/juce_win32_ComSmartPtr.h"\r
+    "../../../../../modules/juce_core/native/juce_win32_Files.cpp"\r
+    "../../../../../modules/juce_core/native/juce_win32_Network.cpp"\r
+    "../../../../../modules/juce_core/native/juce_win32_Registry.cpp"\r
+    "../../../../../modules/juce_core/native/juce_win32_SystemStats.cpp"\r
+    "../../../../../modules/juce_core/native/juce_win32_Threads.cpp"\r
+    "../../../../../modules/juce_core/network/juce_IPAddress.cpp"\r
+    "../../../../../modules/juce_core/network/juce_IPAddress.h"\r
+    "../../../../../modules/juce_core/network/juce_MACAddress.cpp"\r
+    "../../../../../modules/juce_core/network/juce_MACAddress.h"\r
+    "../../../../../modules/juce_core/network/juce_NamedPipe.cpp"\r
+    "../../../../../modules/juce_core/network/juce_NamedPipe.h"\r
+    "../../../../../modules/juce_core/network/juce_Socket.cpp"\r
+    "../../../../../modules/juce_core/network/juce_Socket.h"\r
+    "../../../../../modules/juce_core/network/juce_URL.cpp"\r
+    "../../../../../modules/juce_core/network/juce_URL.h"\r
+    "../../../../../modules/juce_core/network/juce_WebInputStream.cpp"\r
+    "../../../../../modules/juce_core/network/juce_WebInputStream.h"\r
+    "../../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp"\r
+    "../../../../../modules/juce_core/streams/juce_BufferedInputStream.h"\r
+    "../../../../../modules/juce_core/streams/juce_FileInputSource.cpp"\r
+    "../../../../../modules/juce_core/streams/juce_FileInputSource.h"\r
+    "../../../../../modules/juce_core/streams/juce_InputSource.h"\r
+    "../../../../../modules/juce_core/streams/juce_InputStream.cpp"\r
+    "../../../../../modules/juce_core/streams/juce_InputStream.h"\r
+    "../../../../../modules/juce_core/streams/juce_MemoryInputStream.cpp"\r
+    "../../../../../modules/juce_core/streams/juce_MemoryInputStream.h"\r
+    "../../../../../modules/juce_core/streams/juce_MemoryOutputStream.cpp"\r
+    "../../../../../modules/juce_core/streams/juce_MemoryOutputStream.h"\r
+    "../../../../../modules/juce_core/streams/juce_OutputStream.cpp"\r
+    "../../../../../modules/juce_core/streams/juce_OutputStream.h"\r
+    "../../../../../modules/juce_core/streams/juce_SubregionStream.cpp"\r
+    "../../../../../modules/juce_core/streams/juce_SubregionStream.h"\r
+    "../../../../../modules/juce_core/streams/juce_URLInputSource.cpp"\r
+    "../../../../../modules/juce_core/streams/juce_URLInputSource.h"\r
+    "../../../../../modules/juce_core/system/juce_CompilerSupport.h"\r
+    "../../../../../modules/juce_core/system/juce_PlatformDefs.h"\r
+    "../../../../../modules/juce_core/system/juce_StandardHeader.h"\r
+    "../../../../../modules/juce_core/system/juce_SystemStats.cpp"\r
+    "../../../../../modules/juce_core/system/juce_SystemStats.h"\r
+    "../../../../../modules/juce_core/system/juce_TargetPlatform.h"\r
+    "../../../../../modules/juce_core/text/juce_Base64.cpp"\r
+    "../../../../../modules/juce_core/text/juce_Base64.h"\r
+    "../../../../../modules/juce_core/text/juce_CharacterFunctions.cpp"\r
+    "../../../../../modules/juce_core/text/juce_CharacterFunctions.h"\r
+    "../../../../../modules/juce_core/text/juce_CharPointer_ASCII.h"\r
+    "../../../../../modules/juce_core/text/juce_CharPointer_UTF8.h"\r
+    "../../../../../modules/juce_core/text/juce_CharPointer_UTF16.h"\r
+    "../../../../../modules/juce_core/text/juce_CharPointer_UTF32.h"\r
+    "../../../../../modules/juce_core/text/juce_Identifier.cpp"\r
+    "../../../../../modules/juce_core/text/juce_Identifier.h"\r
+    "../../../../../modules/juce_core/text/juce_LocalisedStrings.cpp"\r
+    "../../../../../modules/juce_core/text/juce_LocalisedStrings.h"\r
+    "../../../../../modules/juce_core/text/juce_NewLine.h"\r
+    "../../../../../modules/juce_core/text/juce_String.cpp"\r
+    "../../../../../modules/juce_core/text/juce_String.h"\r
+    "../../../../../modules/juce_core/text/juce_StringArray.cpp"\r
+    "../../../../../modules/juce_core/text/juce_StringArray.h"\r
+    "../../../../../modules/juce_core/text/juce_StringPairArray.cpp"\r
+    "../../../../../modules/juce_core/text/juce_StringPairArray.h"\r
+    "../../../../../modules/juce_core/text/juce_StringPool.cpp"\r
+    "../../../../../modules/juce_core/text/juce_StringPool.h"\r
+    "../../../../../modules/juce_core/text/juce_StringRef.h"\r
+    "../../../../../modules/juce_core/text/juce_TextDiff.cpp"\r
+    "../../../../../modules/juce_core/text/juce_TextDiff.h"\r
+    "../../../../../modules/juce_core/threads/juce_ChildProcess.cpp"\r
+    "../../../../../modules/juce_core/threads/juce_ChildProcess.h"\r
+    "../../../../../modules/juce_core/threads/juce_CriticalSection.h"\r
+    "../../../../../modules/juce_core/threads/juce_DynamicLibrary.h"\r
+    "../../../../../modules/juce_core/threads/juce_HighResolutionTimer.cpp"\r
+    "../../../../../modules/juce_core/threads/juce_HighResolutionTimer.h"\r
+    "../../../../../modules/juce_core/threads/juce_InterProcessLock.h"\r
+    "../../../../../modules/juce_core/threads/juce_Process.h"\r
+    "../../../../../modules/juce_core/threads/juce_ReadWriteLock.cpp"\r
+    "../../../../../modules/juce_core/threads/juce_ReadWriteLock.h"\r
+    "../../../../../modules/juce_core/threads/juce_ScopedLock.h"\r
+    "../../../../../modules/juce_core/threads/juce_ScopedReadLock.h"\r
+    "../../../../../modules/juce_core/threads/juce_ScopedWriteLock.h"\r
+    "../../../../../modules/juce_core/threads/juce_SpinLock.h"\r
+    "../../../../../modules/juce_core/threads/juce_Thread.cpp"\r
+    "../../../../../modules/juce_core/threads/juce_Thread.h"\r
+    "../../../../../modules/juce_core/threads/juce_ThreadLocalValue.h"\r
+    "../../../../../modules/juce_core/threads/juce_ThreadPool.cpp"\r
+    "../../../../../modules/juce_core/threads/juce_ThreadPool.h"\r
+    "../../../../../modules/juce_core/threads/juce_TimeSliceThread.cpp"\r
+    "../../../../../modules/juce_core/threads/juce_TimeSliceThread.h"\r
+    "../../../../../modules/juce_core/threads/juce_WaitableEvent.h"\r
+    "../../../../../modules/juce_core/time/juce_PerformanceCounter.cpp"\r
+    "../../../../../modules/juce_core/time/juce_PerformanceCounter.h"\r
+    "../../../../../modules/juce_core/time/juce_RelativeTime.cpp"\r
+    "../../../../../modules/juce_core/time/juce_RelativeTime.h"\r
+    "../../../../../modules/juce_core/time/juce_Time.cpp"\r
+    "../../../../../modules/juce_core/time/juce_Time.h"\r
+    "../../../../../modules/juce_core/unit_tests/juce_UnitTest.cpp"\r
+    "../../../../../modules/juce_core/unit_tests/juce_UnitTest.h"\r
+    "../../../../../modules/juce_core/xml/juce_XmlDocument.cpp"\r
+    "../../../../../modules/juce_core/xml/juce_XmlDocument.h"\r
+    "../../../../../modules/juce_core/xml/juce_XmlElement.cpp"\r
+    "../../../../../modules/juce_core/xml/juce_XmlElement.h"\r
+    "../../../../../modules/juce_core/zip/zlib/adler32.c"\r
+    "../../../../../modules/juce_core/zip/zlib/compress.c"\r
+    "../../../../../modules/juce_core/zip/zlib/crc32.c"\r
+    "../../../../../modules/juce_core/zip/zlib/crc32.h"\r
+    "../../../../../modules/juce_core/zip/zlib/deflate.c"\r
+    "../../../../../modules/juce_core/zip/zlib/deflate.h"\r
+    "../../../../../modules/juce_core/zip/zlib/infback.c"\r
+    "../../../../../modules/juce_core/zip/zlib/inffast.c"\r
+    "../../../../../modules/juce_core/zip/zlib/inffast.h"\r
+    "../../../../../modules/juce_core/zip/zlib/inffixed.h"\r
+    "../../../../../modules/juce_core/zip/zlib/inflate.c"\r
+    "../../../../../modules/juce_core/zip/zlib/inflate.h"\r
+    "../../../../../modules/juce_core/zip/zlib/inftrees.c"\r
+    "../../../../../modules/juce_core/zip/zlib/inftrees.h"\r
+    "../../../../../modules/juce_core/zip/zlib/trees.c"\r
+    "../../../../../modules/juce_core/zip/zlib/trees.h"\r
+    "../../../../../modules/juce_core/zip/zlib/uncompr.c"\r
+    "../../../../../modules/juce_core/zip/zlib/zconf.h"\r
+    "../../../../../modules/juce_core/zip/zlib/zconf.in.h"\r
+    "../../../../../modules/juce_core/zip/zlib/zlib.h"\r
+    "../../../../../modules/juce_core/zip/zlib/zutil.c"\r
+    "../../../../../modules/juce_core/zip/zlib/zutil.h"\r
+    "../../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp"\r
+    "../../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.h"\r
+    "../../../../../modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp"\r
+    "../../../../../modules/juce_core/zip/juce_GZIPDecompressorInputStream.h"\r
+    "../../../../../modules/juce_core/zip/juce_ZipFile.cpp"\r
+    "../../../../../modules/juce_core/zip/juce_ZipFile.h"\r
+    "../../../../../modules/juce_core/juce_core.cpp"\r
+    "../../../../../modules/juce_core/juce_core.mm"\r
+    "../../../../../modules/juce_core/juce_core.h"\r
+    "../../../../../modules/juce_cryptography/encryption/juce_BlowFish.cpp"\r
+    "../../../../../modules/juce_cryptography/encryption/juce_BlowFish.h"\r
+    "../../../../../modules/juce_cryptography/encryption/juce_Primes.cpp"\r
+    "../../../../../modules/juce_cryptography/encryption/juce_Primes.h"\r
+    "../../../../../modules/juce_cryptography/encryption/juce_RSAKey.cpp"\r
+    "../../../../../modules/juce_cryptography/encryption/juce_RSAKey.h"\r
+    "../../../../../modules/juce_cryptography/hashing/juce_MD5.cpp"\r
+    "../../../../../modules/juce_cryptography/hashing/juce_MD5.h"\r
+    "../../../../../modules/juce_cryptography/hashing/juce_SHA256.cpp"\r
+    "../../../../../modules/juce_cryptography/hashing/juce_SHA256.h"\r
+    "../../../../../modules/juce_cryptography/hashing/juce_Whirlpool.cpp"\r
+    "../../../../../modules/juce_cryptography/hashing/juce_Whirlpool.h"\r
+    "../../../../../modules/juce_cryptography/juce_cryptography.cpp"\r
+    "../../../../../modules/juce_cryptography/juce_cryptography.mm"\r
+    "../../../../../modules/juce_cryptography/juce_cryptography.h"\r
+    "../../../../../modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp"\r
+    "../../../../../modules/juce_data_structures/app_properties/juce_ApplicationProperties.h"\r
+    "../../../../../modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp"\r
+    "../../../../../modules/juce_data_structures/app_properties/juce_PropertiesFile.h"\r
+    "../../../../../modules/juce_data_structures/undomanager/juce_UndoableAction.h"\r
+    "../../../../../modules/juce_data_structures/undomanager/juce_UndoManager.cpp"\r
+    "../../../../../modules/juce_data_structures/undomanager/juce_UndoManager.h"\r
+    "../../../../../modules/juce_data_structures/values/juce_CachedValue.cpp"\r
+    "../../../../../modules/juce_data_structures/values/juce_CachedValue.h"\r
+    "../../../../../modules/juce_data_structures/values/juce_Value.cpp"\r
+    "../../../../../modules/juce_data_structures/values/juce_Value.h"\r
+    "../../../../../modules/juce_data_structures/values/juce_ValueTree.cpp"\r
+    "../../../../../modules/juce_data_structures/values/juce_ValueTree.h"\r
+    "../../../../../modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp"\r
+    "../../../../../modules/juce_data_structures/values/juce_ValueTreeSynchroniser.h"\r
+    "../../../../../modules/juce_data_structures/values/juce_ValueWithDefault.h"\r
+    "../../../../../modules/juce_data_structures/juce_data_structures.cpp"\r
+    "../../../../../modules/juce_data_structures/juce_data_structures.mm"\r
+    "../../../../../modules/juce_data_structures/juce_data_structures.h"\r
+    "../../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp"\r
+    "../../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.h"\r
+    "../../../../../modules/juce_events/broadcasters/juce_ActionListener.h"\r
+    "../../../../../modules/juce_events/broadcasters/juce_AsyncUpdater.cpp"\r
+    "../../../../../modules/juce_events/broadcasters/juce_AsyncUpdater.h"\r
+    "../../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp"\r
+    "../../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.h"\r
+    "../../../../../modules/juce_events/broadcasters/juce_ChangeListener.h"\r
+    "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp"\r
+    "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h"\r
+    "../../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp"\r
+    "../../../../../modules/juce_events/interprocess/juce_InterprocessConnection.h"\r
+    "../../../../../modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp"\r
+    "../../../../../modules/juce_events/interprocess/juce_InterprocessConnectionServer.h"\r
+    "../../../../../modules/juce_events/messages/juce_ApplicationBase.cpp"\r
+    "../../../../../modules/juce_events/messages/juce_ApplicationBase.h"\r
+    "../../../../../modules/juce_events/messages/juce_CallbackMessage.h"\r
+    "../../../../../modules/juce_events/messages/juce_DeletedAtShutdown.cpp"\r
+    "../../../../../modules/juce_events/messages/juce_DeletedAtShutdown.h"\r
+    "../../../../../modules/juce_events/messages/juce_Initialisation.h"\r
+    "../../../../../modules/juce_events/messages/juce_Message.h"\r
+    "../../../../../modules/juce_events/messages/juce_MessageListener.cpp"\r
+    "../../../../../modules/juce_events/messages/juce_MessageListener.h"\r
+    "../../../../../modules/juce_events/messages/juce_MessageManager.cpp"\r
+    "../../../../../modules/juce_events/messages/juce_MessageManager.h"\r
+    "../../../../../modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h"\r
+    "../../../../../modules/juce_events/messages/juce_NotificationType.h"\r
+    "../../../../../modules/juce_events/native/juce_android_Messaging.cpp"\r
+    "../../../../../modules/juce_events/native/juce_ios_MessageManager.mm"\r
+    "../../../../../modules/juce_events/native/juce_linux_EventLoop.h"\r
+    "../../../../../modules/juce_events/native/juce_linux_Messaging.cpp"\r
+    "../../../../../modules/juce_events/native/juce_mac_MessageManager.mm"\r
+    "../../../../../modules/juce_events/native/juce_osx_MessageQueue.h"\r
+    "../../../../../modules/juce_events/native/juce_win32_HiddenMessageWindow.h"\r
+    "../../../../../modules/juce_events/native/juce_win32_Messaging.cpp"\r
+    "../../../../../modules/juce_events/native/juce_win32_WinRTWrapper.cpp"\r
+    "../../../../../modules/juce_events/native/juce_win32_WinRTWrapper.h"\r
+    "../../../../../modules/juce_events/timers/juce_MultiTimer.cpp"\r
+    "../../../../../modules/juce_events/timers/juce_MultiTimer.h"\r
+    "../../../../../modules/juce_events/timers/juce_Timer.cpp"\r
+    "../../../../../modules/juce_events/timers/juce_Timer.h"\r
+    "../../../../../modules/juce_events/juce_events.cpp"\r
+    "../../../../../modules/juce_events/juce_events.mm"\r
+    "../../../../../modules/juce_events/juce_events.h"\r
+    "../../../../../modules/juce_graphics/colour/juce_Colour.cpp"\r
+    "../../../../../modules/juce_graphics/colour/juce_Colour.h"\r
+    "../../../../../modules/juce_graphics/colour/juce_ColourGradient.cpp"\r
+    "../../../../../modules/juce_graphics/colour/juce_ColourGradient.h"\r
+    "../../../../../modules/juce_graphics/colour/juce_Colours.cpp"\r
+    "../../../../../modules/juce_graphics/colour/juce_Colours.h"\r
+    "../../../../../modules/juce_graphics/colour/juce_FillType.cpp"\r
+    "../../../../../modules/juce_graphics/colour/juce_FillType.h"\r
+    "../../../../../modules/juce_graphics/colour/juce_PixelFormats.h"\r
+    "../../../../../modules/juce_graphics/contexts/juce_GraphicsContext.cpp"\r
+    "../../../../../modules/juce_graphics/contexts/juce_GraphicsContext.h"\r
+    "../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"\r
+    "../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp"\r
+    "../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h"\r
+    "../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"\r
+    "../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"\r
+    "../../../../../modules/juce_graphics/effects/juce_DropShadowEffect.cpp"\r
+    "../../../../../modules/juce_graphics/effects/juce_DropShadowEffect.h"\r
+    "../../../../../modules/juce_graphics/effects/juce_GlowEffect.cpp"\r
+    "../../../../../modules/juce_graphics/effects/juce_GlowEffect.h"\r
+    "../../../../../modules/juce_graphics/effects/juce_ImageEffectFilter.h"\r
+    "../../../../../modules/juce_graphics/fonts/juce_AttributedString.cpp"\r
+    "../../../../../modules/juce_graphics/fonts/juce_AttributedString.h"\r
+    "../../../../../modules/juce_graphics/fonts/juce_CustomTypeface.cpp"\r
+    "../../../../../modules/juce_graphics/fonts/juce_CustomTypeface.h"\r
+    "../../../../../modules/juce_graphics/fonts/juce_Font.cpp"\r
+    "../../../../../modules/juce_graphics/fonts/juce_Font.h"\r
+    "../../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.cpp"\r
+    "../../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.h"\r
+    "../../../../../modules/juce_graphics/fonts/juce_TextLayout.cpp"\r
+    "../../../../../modules/juce_graphics/fonts/juce_TextLayout.h"\r
+    "../../../../../modules/juce_graphics/fonts/juce_Typeface.cpp"\r
+    "../../../../../modules/juce_graphics/fonts/juce_Typeface.h"\r
+    "../../../../../modules/juce_graphics/geometry/juce_AffineTransform.cpp"\r
+    "../../../../../modules/juce_graphics/geometry/juce_AffineTransform.h"\r
+    "../../../../../modules/juce_graphics/geometry/juce_BorderSize.h"\r
+    "../../../../../modules/juce_graphics/geometry/juce_EdgeTable.cpp"\r
+    "../../../../../modules/juce_graphics/geometry/juce_EdgeTable.h"\r
+    "../../../../../modules/juce_graphics/geometry/juce_Line.h"\r
+    "../../../../../modules/juce_graphics/geometry/juce_Parallelogram.h"\r
+    "../../../../../modules/juce_graphics/geometry/juce_Path.cpp"\r
+    "../../../../../modules/juce_graphics/geometry/juce_Path.h"\r
+    "../../../../../modules/juce_graphics/geometry/juce_PathIterator.cpp"\r
+    "../../../../../modules/juce_graphics/geometry/juce_PathIterator.h"\r
+    "../../../../../modules/juce_graphics/geometry/juce_PathStrokeType.cpp"\r
+    "../../../../../modules/juce_graphics/geometry/juce_PathStrokeType.h"\r
+    "../../../../../modules/juce_graphics/geometry/juce_Point.h"\r
+    "../../../../../modules/juce_graphics/geometry/juce_Rectangle.h"\r
+    "../../../../../modules/juce_graphics/geometry/juce_RectangleList.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/cderror.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/changes to libjpeg for JUCE.txt"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jcapimin.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jcapistd.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jccoefct.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jccolor.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jcdctmgr.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jchuff.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jchuff.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jcinit.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jcmainct.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jcmarker.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jcmaster.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jcomapi.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jconfig.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jcparam.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jcphuff.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jcprepct.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jcsample.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jctrans.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdapimin.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdapistd.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdatasrc.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdcoefct.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdcolor.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdct.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jddctmgr.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdhuff.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdhuff.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdinput.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdmainct.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdmarker.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdmaster.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdmerge.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdphuff.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdpostct.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdsample.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jdtrans.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jerror.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jerror.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jfdctflt.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jfdctfst.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jfdctint.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jidctflt.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jidctfst.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jidctint.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jidctred.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jinclude.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jmemmgr.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jmemnobs.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jmemsys.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jmorecfg.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jpegint.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jpeglib.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jquant1.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jquant2.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jutils.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/jversion.h"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/transupp.c"\r
+    "../../../../../modules/juce_graphics/image_formats/jpglib/transupp.h"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/libpng_readme.txt"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/png.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/png.h"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngconf.h"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngerror.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngget.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pnginfo.h"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngmem.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngpread.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngpriv.h"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngread.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngrio.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngrtran.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngrutil.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngset.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngstruct.h"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngtrans.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngwio.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngwrite.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngwtran.c"\r
+    "../../../../../modules/juce_graphics/image_formats/pnglib/pngwutil.c"\r
+    "../../../../../modules/juce_graphics/image_formats/juce_GIFLoader.cpp"\r
+    "../../../../../modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"\r
+    "../../../../../modules/juce_graphics/image_formats/juce_PNGLoader.cpp"\r
+    "../../../../../modules/juce_graphics/images/juce_Image.cpp"\r
+    "../../../../../modules/juce_graphics/images/juce_Image.h"\r
+    "../../../../../modules/juce_graphics/images/juce_ImageCache.cpp"\r
+    "../../../../../modules/juce_graphics/images/juce_ImageCache.h"\r
+    "../../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp"\r
+    "../../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.h"\r
+    "../../../../../modules/juce_graphics/images/juce_ImageFileFormat.cpp"\r
+    "../../../../../modules/juce_graphics/images/juce_ImageFileFormat.h"\r
+    "../../../../../modules/juce_graphics/native/juce_android_Fonts.cpp"\r
+    "../../../../../modules/juce_graphics/native/juce_android_GraphicsContext.cpp"\r
+    "../../../../../modules/juce_graphics/native/juce_android_IconHelpers.cpp"\r
+    "../../../../../modules/juce_graphics/native/juce_freetype_Fonts.cpp"\r
+    "../../../../../modules/juce_graphics/native/juce_linux_Fonts.cpp"\r
+    "../../../../../modules/juce_graphics/native/juce_linux_IconHelpers.cpp"\r
+    "../../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h"\r
+    "../../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm"\r
+    "../../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h"\r
+    "../../../../../modules/juce_graphics/native/juce_mac_Fonts.mm"\r
+    "../../../../../modules/juce_graphics/native/juce_mac_IconHelpers.cpp"\r
+    "../../../../../modules/juce_graphics/native/juce_RenderingHelpers.h"\r
+    "../../../../../modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp"\r
+    "../../../../../modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.h"\r
+    "../../../../../modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp"\r
+    "../../../../../modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp"\r
+    "../../../../../modules/juce_graphics/native/juce_win32_Fonts.cpp"\r
+    "../../../../../modules/juce_graphics/native/juce_win32_IconHelpers.cpp"\r
+    "../../../../../modules/juce_graphics/placement/juce_Justification.h"\r
+    "../../../../../modules/juce_graphics/placement/juce_RectanglePlacement.cpp"\r
+    "../../../../../modules/juce_graphics/placement/juce_RectanglePlacement.h"\r
+    "../../../../../modules/juce_graphics/juce_graphics.cpp"\r
+    "../../../../../modules/juce_graphics/juce_graphics.mm"\r
+    "../../../../../modules/juce_graphics/juce_graphics.h"\r
+    "../../../../../modules/juce_gui_basics/application/juce_Application.cpp"\r
+    "../../../../../modules/juce_gui_basics/application/juce_Application.h"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_ArrowButton.cpp"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_ArrowButton.h"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_Button.cpp"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_Button.h"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.cpp"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.h"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_HyperlinkButton.h"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_ImageButton.cpp"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_ImageButton.h"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_ShapeButton.cpp"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_ShapeButton.h"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_TextButton.cpp"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_TextButton.h"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_ToggleButton.cpp"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_ToggleButton.h"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp"\r
+    "../../../../../modules/juce_gui_basics/buttons/juce_ToolbarButton.h"\r
+    "../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandID.h"\r
+    "../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp"\r
+    "../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h"\r
+    "../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp"\r
+    "../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h"\r
+    "../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp"\r
+    "../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h"\r
+    "../../../../../modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp"\r
+    "../../../../../modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h"\r
+    "../../../../../modules/juce_gui_basics/components/juce_CachedComponentImage.h"\r
+    "../../../../../modules/juce_gui_basics/components/juce_Component.cpp"\r
+    "../../../../../modules/juce_gui_basics/components/juce_Component.h"\r
+    "../../../../../modules/juce_gui_basics/components/juce_ComponentListener.cpp"\r
+    "../../../../../modules/juce_gui_basics/components/juce_ComponentListener.h"\r
+    "../../../../../modules/juce_gui_basics/components/juce_Desktop.cpp"\r
+    "../../../../../modules/juce_gui_basics/components/juce_Desktop.h"\r
+    "../../../../../modules/juce_gui_basics/components/juce_ModalComponentManager.cpp"\r
+    "../../../../../modules/juce_gui_basics/components/juce_ModalComponentManager.h"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_Drawable.cpp"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_Drawable.h"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_DrawableComposite.h"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_DrawableImage.cpp"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_DrawableImage.h"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.cpp"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.h"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_DrawableRectangle.h"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_DrawableShape.cpp"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_DrawableShape.h"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_DrawableText.cpp"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_DrawableText.h"\r
+    "../../../../../modules/juce_gui_basics/drawables/juce_SVGParser.cpp"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_ContentSharer.cpp"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_ContentSharer.h"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileChooser.h"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.h"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.h"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.cpp"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.h"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_KeyPress.cpp"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_KeyPress.h"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_ModifierKeys.h"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_SystemClipboard.h"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h"\r
+    "../../../../../modules/juce_gui_basics/keyboard/juce_TextInputTarget.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_AnimatedPosition.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ComponentAnimator.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ComponentBuilder.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_FlexBox.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_FlexBox.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_FlexItem.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_Grid.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_Grid.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_GridItem.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_GridItem.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_GridUnitTests.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_GroupComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_GroupComponent.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ScrollBar.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_ScrollBar.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_SidePanel.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_SidePanel.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_TabbedButtonBar.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.h"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_Viewport.cpp"\r
+    "../../../../../modules/juce_gui_basics/layout/juce_Viewport.h"\r
+    "../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp"\r
+    "../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h"\r
+    "../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp"\r
+    "../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h"\r
+    "../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp"\r
+    "../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h"\r
+    "../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp"\r
+    "../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h"\r
+    "../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp"\r
+    "../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.h"\r
+    "../../../../../modules/juce_gui_basics/menus/juce_BurgerMenuComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/menus/juce_BurgerMenuComponent.h"\r
+    "../../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.h"\r
+    "../../../../../modules/juce_gui_basics/menus/juce_MenuBarModel.cpp"\r
+    "../../../../../modules/juce_gui_basics/menus/juce_MenuBarModel.h"\r
+    "../../../../../modules/juce_gui_basics/menus/juce_PopupMenu.cpp"\r
+    "../../../../../modules/juce_gui_basics/menus/juce_PopupMenu.h"\r
+    "../../../../../modules/juce_gui_basics/misc/juce_BubbleComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/misc/juce_BubbleComponent.h"\r
+    "../../../../../modules/juce_gui_basics/misc/juce_DropShadower.cpp"\r
+    "../../../../../modules/juce_gui_basics/misc/juce_DropShadower.h"\r
+    "../../../../../modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp"\r
+    "../../../../../modules/juce_gui_basics/misc/juce_JUCESplashScreen.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_ComponentDragger.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_LassoComponent.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.cpp"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_MouseEvent.cpp"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_MouseEvent.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_MouseInputSource.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_MouseListener.cpp"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_MouseListener.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h"\r
+    "../../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h"\r
+    "../../../../../modules/juce_gui_basics/native/juce_android_ContentSharer.cpp"\r
+    "../../../../../modules/juce_gui_basics/native/juce_android_FileChooser.cpp"\r
+    "../../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp"\r
+    "../../../../../modules/juce_gui_basics/native/juce_common_MimeTypes.cpp"\r
+    "../../../../../modules/juce_gui_basics/native/juce_ios_ContentSharer.cpp"\r
+    "../../../../../modules/juce_gui_basics/native/juce_ios_FileChooser.mm"\r
+    "../../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm"\r
+    "../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm"\r
+    "../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp"\r
+    "../../../../../modules/juce_gui_basics/native/juce_linux_X11.cpp"\r
+    "../../../../../modules/juce_gui_basics/native/juce_linux_X11.h"\r
+    "../../../../../modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp"\r
+    "../../../../../modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp"\r
+    "../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm"\r
+    "../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm"\r
+    "../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm"\r
+    "../../../../../modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm"\r
+    "../../../../../modules/juce_gui_basics/native/juce_mac_Windowing.mm"\r
+    "../../../../../modules/juce_gui_basics/native/juce_MultiTouchMapper.h"\r
+    "../../../../../modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp"\r
+    "../../../../../modules/juce_gui_basics/native/juce_win32_FileChooser.cpp"\r
+    "../../../../../modules/juce_gui_basics/native/juce_win32_Windowing.cpp"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_MarkerList.cpp"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_MarkerList.h"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.cpp"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.h"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_RelativePointPath.h"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp"\r
+    "../../../../../modules/juce_gui_basics/positioning/juce_RelativeRectangle.h"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.h"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.h"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_TextPropertyComponent.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ComboBox.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ComboBox.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_Label.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_Label.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ListBox.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ListBox.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ProgressBar.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ProgressBar.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_Slider.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_Slider.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_TableListBox.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_TableListBox.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_TextEditor.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_TextEditor.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_Toolbar.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_Toolbar.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_TreeView.cpp"\r
+    "../../../../../modules/juce_gui_basics/widgets/juce_TreeView.h"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_AlertWindow.cpp"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_AlertWindow.h"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_CallOutBox.cpp"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_CallOutBox.h"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.cpp"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.h"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_DialogWindow.cpp"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_DialogWindow.h"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.cpp"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.h"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.h"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_TooltipWindow.cpp"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_TooltipWindow.h"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp"\r
+    "../../../../../modules/juce_gui_basics/windows/juce_TopLevelWindow.h"\r
+    "../../../../../modules/juce_gui_basics/juce_gui_basics.cpp"\r
+    "../../../../../modules/juce_gui_basics/juce_gui_basics.mm"\r
+    "../../../../../modules/juce_gui_basics/juce_gui_basics.h"\r
+    "../../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp"\r
+    "../../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.h"\r
+    "../../../../../modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp"\r
+    "../../../../../modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h"\r
+    "../../../../../modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h"\r
+    "../../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp"\r
+    "../../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h"\r
+    "../../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h"\r
+    "../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp"\r
+    "../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"\r
+    "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"\r
+    "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"\r
+    "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"\r
+    "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h"\r
+    "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"\r
+    "../../../../../modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h"\r
+    "../../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h"\r
+    "../../../../../modules/juce_gui_extra/embedding/juce_UIViewComponent.h"\r
+    "../../../../../modules/juce_gui_extra/embedding/juce_XEmbedComponent.h"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_AppleRemote.h"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_ColourSelector.cpp"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_ColourSelector.h"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.h"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_PreferencesPanel.h"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_PushNotifications.cpp"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_PushNotifications.h"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_SplashScreen.cpp"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_SplashScreen.h"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"\r
+    "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"\r
+    "../../../../../modules/juce_gui_extra/native/juce_android_PushNotifications.cpp"\r
+    "../../../../../modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp"\r
+    "../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp"\r
+    "../../../../../modules/juce_gui_extra/native/juce_ios_PushNotifications.cpp"\r
+    "../../../../../modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm"\r
+    "../../../../../modules/juce_gui_extra/native/juce_linux_X11_SystemTrayIcon.cpp"\r
+    "../../../../../modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp"\r
+    "../../../../../modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp"\r
+    "../../../../../modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"\r
+    "../../../../../modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h"\r
+    "../../../../../modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm"\r
+    "../../../../../modules/juce_gui_extra/native/juce_mac_PushNotifications.cpp"\r
+    "../../../../../modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp"\r
+    "../../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm"\r
+    "../../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp"\r
+    "../../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp"\r
+    "../../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp"\r
+    "../../../../../modules/juce_gui_extra/juce_gui_extra.cpp"\r
+    "../../../../../modules/juce_gui_extra/juce_gui_extra.mm"\r
+    "../../../../../modules/juce_gui_extra/juce_gui_extra.h"\r
+    "../../../../../modules/juce_opengl/geometry/juce_Draggable3DOrientation.h"\r
+    "../../../../../modules/juce_opengl/geometry/juce_Matrix3D.h"\r
+    "../../../../../modules/juce_opengl/geometry/juce_Quaternion.h"\r
+    "../../../../../modules/juce_opengl/geometry/juce_Vector3D.h"\r
+    "../../../../../modules/juce_opengl/native/juce_MissingGLDefinitions.h"\r
+    "../../../../../modules/juce_opengl/native/juce_OpenGL_android.h"\r
+    "../../../../../modules/juce_opengl/native/juce_OpenGL_ios.h"\r
+    "../../../../../modules/juce_opengl/native/juce_OpenGL_linux_X11.h"\r
+    "../../../../../modules/juce_opengl/native/juce_OpenGL_osx.h"\r
+    "../../../../../modules/juce_opengl/native/juce_OpenGL_win32.h"\r
+    "../../../../../modules/juce_opengl/native/juce_OpenGLExtensions.h"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLContext.cpp"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLContext.h"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLHelpers.h"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLImage.cpp"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLImage.h"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLPixelFormat.cpp"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLPixelFormat.h"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLRenderer.h"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLTexture.cpp"\r
+    "../../../../../modules/juce_opengl/opengl/juce_OpenGLTexture.h"\r
+    "../../../../../modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp"\r
+    "../../../../../modules/juce_opengl/utils/juce_OpenGLAppComponent.h"\r
+    "../../../../../modules/juce_opengl/juce_opengl.cpp"\r
+    "../../../../../modules/juce_opengl/juce_opengl.mm"\r
+    "../../../../../modules/juce_opengl/juce_opengl.h"\r
+    "../../../../../modules/juce_video/capture/juce_CameraDevice.cpp"\r
+    "../../../../../modules/juce_video/capture/juce_CameraDevice.h"\r
+    "../../../../../modules/juce_video/native/juce_android_CameraDevice.h"\r
+    "../../../../../modules/juce_video/native/juce_mac_CameraDevice.h"\r
+    "../../../../../modules/juce_video/native/juce_mac_Video.h"\r
+    "../../../../../modules/juce_video/native/juce_win32_CameraDevice.h"\r
+    "../../../../../modules/juce_video/native/juce_win32_Video.h"\r
+    "../../../../../modules/juce_video/playback/juce_VideoComponent.cpp"\r
+    "../../../../../modules/juce_video/playback/juce_VideoComponent.h"\r
+    "../../../../../modules/juce_video/juce_video.cpp"\r
+    "../../../../../modules/juce_video/juce_video.mm"\r
+    "../../../../../modules/juce_video/juce_video.h"\r
+    "../../../JuceLibraryCode/AppConfig.h"\r
+    "../../../JuceLibraryCode/BinaryData.cpp"\r
+    "../../../JuceLibraryCode/BinaryData.h"\r
+    "../../../JuceLibraryCode/include_juce_audio_basics.cpp"\r
+    "../../../JuceLibraryCode/include_juce_audio_devices.cpp"\r
+    "../../../JuceLibraryCode/include_juce_audio_formats.cpp"\r
+    "../../../JuceLibraryCode/include_juce_audio_processors.cpp"\r
+    "../../../JuceLibraryCode/include_juce_audio_utils.cpp"\r
+    "../../../JuceLibraryCode/include_juce_core.cpp"\r
+    "../../../JuceLibraryCode/include_juce_cryptography.cpp"\r
+    "../../../JuceLibraryCode/include_juce_data_structures.cpp"\r
+    "../../../JuceLibraryCode/include_juce_events.cpp"\r
+    "../../../JuceLibraryCode/include_juce_graphics.cpp"\r
+    "../../../JuceLibraryCode/include_juce_gui_basics.cpp"\r
+    "../../../JuceLibraryCode/include_juce_gui_extra.cpp"\r
+    "../../../JuceLibraryCode/include_juce_opengl.cpp"\r
+    "../../../JuceLibraryCode/include_juce_video.cpp"\r
+    "../../../JuceLibraryCode/JuceHeader.h"\r
+)\r
+\r
+set_source_files_properties("../../../Source/Filters/FilterGraph.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../Source/Filters/FilterIOConfiguration.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../Source/Filters/InternalFilters.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../Source/UI/GraphEditorPanel.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../Source/UI/MainHostWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../Source/UI/PluginWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../Source/JUCEAppIcon.png" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/buffers/juce_AudioChannelSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/buffers/juce_AudioDataConverters.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/effects/juce_Decibels.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/effects/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/effects/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/effects/juce_LinearSmoothedValue.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/effects/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/midi/juce_MidiBuffer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/midi/juce_MidiBuffer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/midi/juce_MidiFile.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/midi/juce_MidiFile.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/midi/juce_MidiKeyboardState.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/midi/juce_MidiMessage.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/midi/juce_MidiMessage.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/midi/juce_MidiMessageSequence.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/midi/juce_MidiRPN.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/midi/juce_MidiRPN.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPEInstrument.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPEMessages.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPEMessages.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPENote.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPENote.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiser.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPEUtils.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPEUtils.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPEValue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPEValue.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_AudioSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_BufferingAudioSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_MemoryAudioSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_MixerAudioSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_PositionableAudioSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_ReverbAudioSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/audio_io/juce_AudioIODevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiInput.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiOutput.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Oboe.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_OpenSL.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_ios_Audio.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_Bela.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_JackAudio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_Midi.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_MidiDataConcatenator.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_win32_ASIO.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_win32_DirectSound.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_win32_Midi.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_win32_WASAPI.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/sources/juce_AudioTransportSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/juce_audio_devices.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/juce_audio_devices.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/juce_audio_devices.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/cpu.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/crc.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/fixed.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/float.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/format.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/cpu.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/crc.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/fixed.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/float.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/format.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/md5.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/memory.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder_framing.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/window_flac.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/all.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/alloc.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/assert.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/callback.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/compat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/endswap.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/export.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/Flac Licence.txt" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/format.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/metadata.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/ordinals.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/win_utf8_io.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+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)\r
+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)\r
+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)\r
+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)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/floor_all.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_8.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_11.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_16.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_44.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_8.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_16.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_8.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_11.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_16.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_22.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_32.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_X.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/analysis.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/backends.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/block.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codec_internal.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor0.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor1.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/highlevel.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/info.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup_data.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mapping0.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/masking.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/misc.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/res0.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/scales.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/sharedbook.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/synthesis.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/bitwise.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/codec.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/config_types.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/framing.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/Ogg Vorbis Licence.txt" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/ogg.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/os_types.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/vorbisenc.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/vorbisfile.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_WavAudioFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_AudioFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_AudioFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_AudioFormatManager.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_AudioFormatManager.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_AudioFormatReader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_AudioFormatReader.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/sampler/juce_Sampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/sampler/juce_Sampler.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/juce_audio_formats.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/juce_audio_formats.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_formats/juce_audio_formats.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format/juce_AudioPluginFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_AU_Shared.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3Common.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3Headers.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VSTCommon.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VSTInterface.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_AudioPluginInstance.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_AudioPluginInstance.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_PluginDescription.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/processors/juce_PluginDescription.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/scanning/juce_KnownPluginList.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/scanning/juce_PluginListComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioParameterBool.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioParameterInt.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/juce_audio_processors.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/juce_audio_processors.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/juce_audio_processors.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/audio_cd/juce_AudioCDBurner.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/audio_cd/juce_AudioCDReader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/audio_cd/juce_AudioCDReader.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_AudioAppComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_AudioAppComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_AudioThumbnail.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_AudioThumbnailBase.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_AudioThumbnailCache.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_BluetoothMidiDevicePairingDialogue.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/native/juce_android_BluetoothMidiDevicePairingDialogue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/native/juce_ios_BluetoothMidiDevicePairingDialogue.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/native/juce_linux_AudioCDReader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/native/juce_linux_BluetoothMidiDevicePairingDialogue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/native/juce_mac_AudioCDBurner.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/native/juce_mac_AudioCDReader.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/native/juce_mac_BluetoothMidiDevicePairingDialogue.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/native/juce_win_BluetoothMidiDevicePairingDialogue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/native/juce_win32_AudioCDBurner.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/native/juce_win32_AudioCDReader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/players/juce_AudioProcessorPlayer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/players/juce_SoundPlayer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/players/juce_SoundPlayer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/juce_audio_utils.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/juce_audio_utils.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_utils/juce_audio_utils.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_AbstractFifo.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_AbstractFifo.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_Array.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_ArrayAllocationBase.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_DynamicObject.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_DynamicObject.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_ElementComparator.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_HashMap.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_HashMap_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_LinkedListPointer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_ListenerList.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_NamedValueSet.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_NamedValueSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_OwnedArray.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_PropertySet.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_PropertySet.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_ScopedValueSetter.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_SortedSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_SparseSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_Variant.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/containers/juce_Variant.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_DirectoryIterator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_DirectoryIterator.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_File.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_File.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_FileFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_FileFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_FileInputStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_FileInputStream.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_FileOutputStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_FileOutputStream.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_FileSearchPath.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_FileSearchPath.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_MemoryMappedFile.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_TemporaryFile.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_TemporaryFile.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/files/juce_WildcardFileFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/javascript/juce_Javascript.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/javascript/juce_Javascript.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/javascript/juce_JSON.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/javascript/juce_JSON.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/logging/juce_FileLogger.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/logging/juce_FileLogger.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/logging/juce_Logger.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/logging/juce_Logger.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/maths/juce_BigInteger.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/maths/juce_BigInteger.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/maths/juce_Expression.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/maths/juce_Expression.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/maths/juce_MathsFunctions.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/maths/juce_NormalisableRange.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/maths/juce_Random.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/maths/juce_Random.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/maths/juce_Range.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/maths/juce_StatisticsAccumulator.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_Atomic.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_ByteOrder.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_ContainerDeletePolicy.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_HeapBlock.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_LeakedObjectDetector.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_Memory.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_MemoryBlock.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_MemoryBlock.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_OptionalScopedPointer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_ReferenceCountedObject.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_ScopedPointer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_Singleton.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/memory/juce_WeakReference.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/misc/juce_Result.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/misc/juce_Result.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/misc/juce_RuntimePermissions.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/misc/juce_StdFunctionCompat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/misc/juce_StdFunctionCompat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/misc/juce_Uuid.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/misc/juce_Uuid.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/misc/juce_WindowsRegistry.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_android_Files.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_android_JNIHelpers.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_android_Misc.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_android_Network.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_android_RuntimePermissions.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_android_SystemStats.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_android_Threads.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_BasicNativeHeaders.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_curl_Network.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_linux_CommonFile.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_linux_Files.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_linux_Network.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_linux_SystemStats.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_linux_Threads.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_mac_ClangBugWorkaround.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_mac_Files.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_mac_Network.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_mac_Strings.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_mac_SystemStats.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_mac_Threads.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_osx_ObjCHelpers.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_posix_NamedPipe.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_posix_SharedCode.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_win32_ComSmartPtr.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_win32_Files.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_win32_Network.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_win32_Registry.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_win32_SystemStats.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/native/juce_win32_Threads.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/network/juce_IPAddress.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/network/juce_IPAddress.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/network/juce_MACAddress.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/network/juce_MACAddress.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/network/juce_NamedPipe.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/network/juce_NamedPipe.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/network/juce_Socket.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/network/juce_Socket.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/network/juce_URL.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/network/juce_URL.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/network/juce_WebInputStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/network/juce_WebInputStream.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_BufferedInputStream.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_FileInputSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_FileInputSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_InputSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_InputStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_InputStream.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_MemoryInputStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_MemoryInputStream.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_MemoryOutputStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_MemoryOutputStream.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_OutputStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_OutputStream.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_SubregionStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_SubregionStream.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_URLInputSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/streams/juce_URLInputSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/system/juce_CompilerSupport.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/system/juce_PlatformDefs.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/system/juce_StandardHeader.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/system/juce_SystemStats.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/system/juce_SystemStats.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/system/juce_TargetPlatform.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_Base64.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_Base64.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_CharacterFunctions.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_CharacterFunctions.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_CharPointer_ASCII.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_CharPointer_UTF8.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_CharPointer_UTF16.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_CharPointer_UTF32.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_Identifier.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_Identifier.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_LocalisedStrings.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_LocalisedStrings.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_NewLine.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_String.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_String.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_StringArray.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_StringArray.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_StringPairArray.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_StringPairArray.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_StringPool.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_StringPool.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_StringRef.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_TextDiff.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/text/juce_TextDiff.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_ChildProcess.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_ChildProcess.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_CriticalSection.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_DynamicLibrary.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_HighResolutionTimer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_HighResolutionTimer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_InterProcessLock.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_Process.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_ReadWriteLock.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_ReadWriteLock.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_ScopedLock.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_ScopedReadLock.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_ScopedWriteLock.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_SpinLock.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_Thread.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_Thread.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_ThreadLocalValue.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_ThreadPool.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_ThreadPool.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_TimeSliceThread.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_TimeSliceThread.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/threads/juce_WaitableEvent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/time/juce_PerformanceCounter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/time/juce_PerformanceCounter.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/time/juce_RelativeTime.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/time/juce_RelativeTime.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/time/juce_Time.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/time/juce_Time.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/unit_tests/juce_UnitTest.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/unit_tests/juce_UnitTest.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/xml/juce_XmlDocument.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/xml/juce_XmlDocument.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/xml/juce_XmlElement.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/xml/juce_XmlElement.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/adler32.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/compress.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/crc32.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/crc32.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/deflate.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/deflate.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/infback.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/inffast.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/inffast.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/inffixed.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/inflate.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/inflate.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/inftrees.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/inftrees.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/trees.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/trees.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/uncompr.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/zconf.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/zconf.in.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/zlib.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/zutil.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/zlib/zutil.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/juce_GZIPDecompressorInputStream.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/juce_ZipFile.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/zip/juce_ZipFile.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/juce_core.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/juce_core.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_core/juce_core.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/encryption/juce_BlowFish.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/encryption/juce_BlowFish.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/encryption/juce_Primes.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/encryption/juce_Primes.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/encryption/juce_RSAKey.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/encryption/juce_RSAKey.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/hashing/juce_MD5.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/hashing/juce_MD5.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/hashing/juce_SHA256.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/hashing/juce_SHA256.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/hashing/juce_Whirlpool.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/hashing/juce_Whirlpool.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/juce_cryptography.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/juce_cryptography.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_cryptography/juce_cryptography.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/app_properties/juce_ApplicationProperties.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/app_properties/juce_PropertiesFile.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/undomanager/juce_UndoableAction.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/undomanager/juce_UndoManager.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/undomanager/juce_UndoManager.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/values/juce_CachedValue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/values/juce_CachedValue.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/values/juce_Value.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/values/juce_Value.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/values/juce_ValueTree.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/values/juce_ValueTree.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/values/juce_ValueTreeSynchroniser.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/values/juce_ValueWithDefault.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/juce_data_structures.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/juce_data_structures.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_data_structures/juce_data_structures.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/broadcasters/juce_ActionListener.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/broadcasters/juce_AsyncUpdater.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/broadcasters/juce_AsyncUpdater.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/broadcasters/juce_ChangeListener.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/interprocess/juce_InterprocessConnection.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/interprocess/juce_InterprocessConnectionServer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_ApplicationBase.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_ApplicationBase.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_CallbackMessage.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_DeletedAtShutdown.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_DeletedAtShutdown.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_Initialisation.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_Message.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_MessageListener.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_MessageListener.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_MessageManager.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_MessageManager.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/messages/juce_NotificationType.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/native/juce_android_Messaging.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/native/juce_ios_MessageManager.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/native/juce_linux_EventLoop.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/native/juce_linux_Messaging.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/native/juce_mac_MessageManager.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/native/juce_osx_MessageQueue.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/native/juce_win32_HiddenMessageWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/native/juce_win32_Messaging.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/native/juce_win32_WinRTWrapper.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/native/juce_win32_WinRTWrapper.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/timers/juce_MultiTimer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/timers/juce_MultiTimer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/timers/juce_Timer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/timers/juce_Timer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/juce_events.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/juce_events.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_events/juce_events.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/colour/juce_Colour.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/colour/juce_Colour.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/colour/juce_ColourGradient.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/colour/juce_ColourGradient.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/colour/juce_Colours.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/colour/juce_Colours.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/colour/juce_FillType.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/colour/juce_FillType.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/colour/juce_PixelFormats.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/contexts/juce_GraphicsContext.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/contexts/juce_GraphicsContext.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/effects/juce_DropShadowEffect.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/effects/juce_DropShadowEffect.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/effects/juce_GlowEffect.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/effects/juce_GlowEffect.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/effects/juce_ImageEffectFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/fonts/juce_AttributedString.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/fonts/juce_AttributedString.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/fonts/juce_CustomTypeface.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/fonts/juce_CustomTypeface.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/fonts/juce_Font.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/fonts/juce_Font.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/fonts/juce_TextLayout.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/fonts/juce_TextLayout.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/fonts/juce_Typeface.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/fonts/juce_Typeface.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_AffineTransform.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_AffineTransform.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_BorderSize.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_EdgeTable.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_EdgeTable.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_Line.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_Parallelogram.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_Path.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_Path.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_PathIterator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_PathIterator.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_PathStrokeType.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_PathStrokeType.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_Point.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_Rectangle.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/geometry/juce_RectangleList.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/cderror.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/changes to libjpeg for JUCE.txt" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jcapimin.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jcapistd.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jccoefct.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jccolor.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jcdctmgr.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jchuff.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jchuff.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jcinit.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jcmainct.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jcmarker.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jcmaster.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jcomapi.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jconfig.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jcparam.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jcphuff.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jcprepct.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jcsample.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jctrans.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdapimin.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdapistd.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdatasrc.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdcoefct.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdcolor.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdct.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jddctmgr.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdhuff.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdhuff.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdinput.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdmainct.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdmarker.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdmaster.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdmerge.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdphuff.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdpostct.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdsample.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jdtrans.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jerror.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jerror.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jfdctflt.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jfdctfst.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jfdctint.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jidctflt.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jidctfst.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jidctint.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jidctred.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jinclude.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jmemmgr.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jmemnobs.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jmemsys.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jmorecfg.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jpegint.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jpeglib.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jquant1.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jquant2.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jutils.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/jversion.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/transupp.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/jpglib/transupp.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/libpng_readme.txt" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/png.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/png.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngconf.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngerror.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngget.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pnginfo.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngmem.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngpread.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngpriv.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngread.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngrio.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngrtran.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngrutil.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngset.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngstruct.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngtrans.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngwio.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngwrite.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngwtran.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/pnglib/pngwutil.c" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/juce_GIFLoader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/juce_JPEGLoader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/image_formats/juce_PNGLoader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/images/juce_Image.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/images/juce_Image.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/images/juce_ImageCache.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/images/juce_ImageCache.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/images/juce_ImageFileFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/images/juce_ImageFileFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_android_Fonts.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_android_GraphicsContext.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_android_IconHelpers.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_freetype_Fonts.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_linux_Fonts.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_linux_IconHelpers.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_mac_Fonts.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_mac_IconHelpers.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_RenderingHelpers.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_win32_Fonts.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/native/juce_win32_IconHelpers.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/placement/juce_Justification.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/placement/juce_RectanglePlacement.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/placement/juce_RectanglePlacement.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/juce_graphics.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/juce_graphics.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_graphics/juce_graphics.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/application/juce_Application.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/application/juce_Application.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_ArrowButton.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_ArrowButton.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_Button.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_Button.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_HyperlinkButton.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_ImageButton.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_ImageButton.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_ShapeButton.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_ShapeButton.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_TextButton.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_TextButton.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_ToggleButton.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_ToggleButton.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/buttons/juce_ToolbarButton.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandID.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/components/juce_CachedComponentImage.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/components/juce_Component.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/components/juce_Component.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/components/juce_ComponentListener.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/components/juce_ComponentListener.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/components/juce_Desktop.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/components/juce_Desktop.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/components/juce_ModalComponentManager.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/components/juce_ModalComponentManager.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_Drawable.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_Drawable.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_DrawableComposite.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_DrawableImage.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_DrawableImage.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_DrawableRectangle.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_DrawableShape.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_DrawableShape.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_DrawableText.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_DrawableText.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/drawables/juce_SVGParser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_ContentSharer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_ContentSharer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileChooser.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_KeyPress.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_KeyPress.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_ModifierKeys.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_SystemClipboard.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/keyboard/juce_TextInputTarget.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_AnimatedPosition.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ComponentAnimator.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ComponentBuilder.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_FlexBox.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_FlexBox.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_FlexItem.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_Grid.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_Grid.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_GridItem.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_GridItem.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_GridUnitTests.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_GroupComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_GroupComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ScrollBar.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_ScrollBar.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_SidePanel.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_SidePanel.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_TabbedButtonBar.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_Viewport.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/layout/juce_Viewport.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/menus/juce_BurgerMenuComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/menus/juce_BurgerMenuComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/menus/juce_MenuBarModel.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/menus/juce_MenuBarModel.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/menus/juce_PopupMenu.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/menus/juce_PopupMenu.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/misc/juce_BubbleComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/misc/juce_BubbleComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/misc/juce_DropShadower.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/misc/juce_DropShadower.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/misc/juce_JUCESplashScreen.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_ComponentDragger.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_LassoComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_MouseEvent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_MouseEvent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_MouseInputSource.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_MouseListener.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_MouseListener.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_ContentSharer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_common_MimeTypes.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_ContentSharer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_FileChooser.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_Windowing.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_MultiTouchMapper.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_win32_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_win32_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_MarkerList.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_MarkerList.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_RelativePointPath.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/positioning/juce_RelativeRectangle.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_TextPropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ComboBox.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ComboBox.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_Label.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_Label.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ListBox.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ListBox.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ProgressBar.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ProgressBar.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_Slider.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_Slider.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_TableListBox.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_TableListBox.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_TextEditor.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_TextEditor.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_Toolbar.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_Toolbar.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_TreeView.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/widgets/juce_TreeView.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_AlertWindow.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_AlertWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_CallOutBox.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_CallOutBox.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_DialogWindow.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_DialogWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_TooltipWindow.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_TooltipWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/windows/juce_TopLevelWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/juce_gui_basics.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/juce_gui_basics.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/juce_gui_basics.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_UIViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_XEmbedComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_AppleRemote.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_ColourSelector.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_ColourSelector.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_PreferencesPanel.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_PushNotifications.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_PushNotifications.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_SplashScreen.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_SplashScreen.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_android_PushNotifications.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_ios_PushNotifications.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_linux_X11_SystemTrayIcon.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_AppleRemote.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_PushNotifications.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/juce_gui_extra.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/juce_gui_extra.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_extra/juce_gui_extra.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/geometry/juce_Draggable3DOrientation.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/geometry/juce_Matrix3D.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/geometry/juce_Quaternion.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/geometry/juce_Vector3D.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/native/juce_MissingGLDefinitions.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/native/juce_OpenGL_android.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/native/juce_OpenGL_ios.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/native/juce_OpenGL_linux_X11.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/native/juce_OpenGL_osx.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/native/juce_OpenGL_win32.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/native/juce_OpenGLExtensions.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLContext.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLContext.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLHelpers.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLImage.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLImage.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLPixelFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLPixelFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLRenderer.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLTexture.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/opengl/juce_OpenGLTexture.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/utils/juce_OpenGLAppComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/juce_opengl.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/juce_opengl.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_opengl/juce_opengl.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_video/capture/juce_CameraDevice.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_video/capture/juce_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_video/native/juce_android_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_video/native/juce_mac_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_video/native/juce_mac_Video.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_video/native/juce_win32_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_video/native/juce_win32_Video.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_video/playback/juce_VideoComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_video/playback/juce_VideoComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_video/juce_video.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_video/juce_video.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_video/juce_video.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../JuceLibraryCode/AppConfig.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../JuceLibraryCode/BinaryData.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../JuceLibraryCode/JuceHeader.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+\r
+find_library(log "log")\r
+find_library(android "android")\r
+find_library(glesv3 "GLESv3")\r
+find_library(egl "EGL")\r
+\r
+target_link_libraries( ${BINARY_NAME}\r
+\r
+    ${log}\r
+    ${android}\r
+    ${glesv3}\r
+    ${egl}\r
+    "cpufeatures"\r
+)\r
diff --git a/extras/AudioPluginHost/Builds/Android/app/build.gradle b/extras/AudioPluginHost/Builds/Android/app/build.gradle
new file mode 100644 (file)
index 0000000..e6e07fc
--- /dev/null
@@ -0,0 +1,94 @@
+apply plugin: 'com.android.application'\r
+\r
+android {\r
+    compileSdkVersion 23\r
+    buildToolsVersion "27.0.3"\r
+    externalNativeBuild {\r
+        cmake {\r
+            path "CMakeLists.txt"\r
+        }\r
+    }\r
+    signingConfigs {\r
+        juceSigning {\r
+            storeFile     file("${System.properties['user.home']}${File.separator}.android${File.separator}debug.keystore")\r
+            storePassword "android"\r
+            keyAlias      "androiddebugkey"\r
+            keyPassword   "android"\r
+            storeType     "jks"\r
+        }\r
+    }\r
+\r
+    defaultConfig {\r
+        applicationId "com.roli.juce.pluginhost"\r
+        minSdkVersion    23\r
+        targetSdkVersion 23\r
+        externalNativeBuild {\r
+            cmake {\r
+                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"\r
+                cFlags "-fsigned-char"\r
+                cppFlags "-fsigned-char", "-std=c++14"\r
+            }\r
+        }\r
+    }\r
+\r
+    buildTypes {\r
+         debug {\r
+             initWith debug\r
+             debuggable    true\r
+             jniDebuggable true\r
+             signingConfig signingConfigs.juceSigning\r
+         }\r
+         release {\r
+             initWith release\r
+             debuggable    false\r
+             jniDebuggable false\r
+             signingConfig signingConfigs.juceSigning\r
+         }\r
+    }\r
+\r
+    flavorDimensions "default"\r
+    productFlavors {\r
+        debug_ {\r
+            ndk {\r
+                abiFilters "armeabi", "x86"\r
+            }\r
+            externalNativeBuild {\r
+                cmake {\r
+                    arguments "-DJUCE_BUILD_CONFIGURATION=DEBUG", "-DCMAKE_CXX_FLAGS_DEBUG=-O0", "-DCMAKE_C_FLAGS_DEBUG=-O0"\r
+                }\r
+            }\r
+\r
+            dimension "default"\r
+       }\r
+        release_ {\r
+            externalNativeBuild {\r
+                cmake {\r
+                    arguments "-DJUCE_BUILD_CONFIGURATION=RELEASE", "-DCMAKE_CXX_FLAGS_RELEASE=-O3", "-DCMAKE_C_FLAGS_RELEASE=-O3"\r
+                }\r
+            }\r
+\r
+            dimension "default"\r
+       }\r
+    }\r
+\r
+    variantFilter { variant ->\r
+        def names = variant.flavors*.name\r
+        if (names.contains ("debug_")\r
+              && variant.buildType.name != "debug") {\r
+            setIgnore(true)\r
+        }\r
+        if (names.contains ("release_")\r
+              && variant.buildType.name != "release") {\r
+            setIgnore(true)\r
+        }\r
+    }\r
+\r
+repositories {\r
+}\r
+\r
+dependencies {\r
+}\r
+\r
+\r
+}\r
+\r
diff --git a/extras/AudioPluginHost/Builds/Android/app/src/debug/res/values/string.xml b/extras/AudioPluginHost/Builds/Android/app/src/debug/res/values/string.xml
new file mode 100644 (file)
index 0000000..bed17a5
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<resources>
+  <string name="app_name">AudioPluginHost</string>
+</resources>
diff --git a/extras/AudioPluginHost/Builds/Android/app/src/main/AndroidManifest.xml b/extras/AudioPluginHost/Builds/Android/app/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..df2ca3d
--- /dev/null
@@ -0,0 +1,24 @@
+<?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"/>
+  <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23"/>
+  <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.BLUETOOTH_ADMIN"/>
+  <uses-permission android:name="android.permission.BLUETOOTH"/>
+  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+  <uses-permission android:name="android.permission.INTERNET"/>
+  <uses-feature android:glEsVersion="0x00030000" android:required="true"/>
+  <application android:label="@string/app_name" android:icon="@drawable/icon" android:hardwareAccelerated="false">
+    <activity android:name="AudioPluginHost" 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"/>
+        <category android:name="android.intent.category.LAUNCHER"/>
+      </intent-filter>
+    </activity>
+  </application>
+</manifest>
diff --git a/extras/AudioPluginHost/Builds/Android/app/src/main/java/com/android/vending/billing/IInAppBillingService.java b/extras/AudioPluginHost/Builds/Android/app/src/main/java/com/android/vending/billing/IInAppBillingService.java
new file mode 100644 (file)
index 0000000..0bb31cb
--- /dev/null
@@ -0,0 +1,971 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   The code included in this file is provided under the terms of the ISC license\r
+   http://www.isc.org/downloads/software-support-policy/isc-license. Permission\r
+   To use, copy, modify, and/or distribute this software for any purpose with or\r
+   without fee is hereby granted provided that the above copyright notice and\r
+   this permission notice appear in all copies.\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+package com.android.vending.billing;\r
+/**\r
+ * InAppBillingService is the service that provides in-app billing version 3 and beyond.\r
+ * This service provides the following features:\r
+ * 1. Provides a new API to get details of in-app items published for the app including\r
+ *    price, type, title and description.\r
+ * 2. The purchase flow is synchronous and purchase information is available immediately\r
+ *    after it completes.\r
+ * 3. Purchase information of in-app purchases is maintained within the Google Play system\r
+ *    till the purchase is consumed.\r
+ * 4. An API to consume a purchase of an inapp item. All purchases of one-time\r
+ *    in-app items are consumable and thereafter can be purchased again.\r
+ * 5. An API to get current purchases of the user immediately. This will not contain any\r
+ *    consumed purchases.\r
+ *\r
+ * All calls will give a response code with the following possible values\r
+ * RESULT_OK = 0 - success\r
+ * RESULT_USER_CANCELED = 1 - User pressed back or canceled a dialog\r
+ * RESULT_SERVICE_UNAVAILABLE = 2 - The network connection is down\r
+ * RESULT_BILLING_UNAVAILABLE = 3 - This billing API version is not supported for the type requested\r
+ * RESULT_ITEM_UNAVAILABLE = 4 - Requested SKU is not available for purchase\r
+ * RESULT_DEVELOPER_ERROR = 5 - Invalid arguments provided to the API\r
+ * RESULT_ERROR = 6 - Fatal error during the API action\r
+ * RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned\r
+ * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned\r
+ */\r
+public interface IInAppBillingService extends android.os.IInterface\r
+    {\r
+        /** Local-side IPC implementation stub class. */\r
+        public static abstract class Stub extends android.os.Binder implements com.android.vending.billing.IInAppBillingService\r
+        {\r
+            private static final java.lang.String DESCRIPTOR = "com.android.vending.billing.IInAppBillingService";\r
+            /** Construct the stub at attach it to the interface. */\r
+            public Stub()\r
+            {\r
+                this.attachInterface(this, DESCRIPTOR);\r
+            }\r
+            /**\r
+             * Cast an IBinder object into an com.android.vending.billing.IInAppBillingService interface,\r
+             * generating a proxy if needed.\r
+             */\r
+            public static com.android.vending.billing.IInAppBillingService asInterface(android.os.IBinder obj)\r
+            {\r
+                if ((obj==null)) {\r
+                    return null;\r
+                }\r
+                android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);\r
+                if (((iin!=null)&&(iin instanceof com.android.vending.billing.IInAppBillingService))) {\r
+                    return ((com.android.vending.billing.IInAppBillingService)iin);\r
+                }\r
+                return new com.android.vending.billing.IInAppBillingService.Stub.Proxy(obj);\r
+            }\r
+            @Override public android.os.IBinder asBinder()\r
+            {\r
+                return this;\r
+            }\r
+            @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException\r
+            {\r
+                switch (code)\r
+                {\r
+                    case INTERFACE_TRANSACTION:\r
+                    {\r
+                        reply.writeString(DESCRIPTOR);\r
+                        return true;\r
+                    }\r
+                    case TRANSACTION_isBillingSupported:\r
+                    {\r
+                        data.enforceInterface(DESCRIPTOR);\r
+                        int _arg0;\r
+                        _arg0 = data.readInt();\r
+                        java.lang.String _arg1;\r
+                        _arg1 = data.readString();\r
+                        java.lang.String _arg2;\r
+                        _arg2 = data.readString();\r
+                        int _result = this.isBillingSupported(_arg0, _arg1, _arg2);\r
+                        reply.writeNoException();\r
+                        reply.writeInt(_result);\r
+                        return true;\r
+                    }\r
+                    case TRANSACTION_getSkuDetails:\r
+                    {\r
+                        data.enforceInterface(DESCRIPTOR);\r
+                        int _arg0;\r
+                        _arg0 = data.readInt();\r
+                        java.lang.String _arg1;\r
+                        _arg1 = data.readString();\r
+                        java.lang.String _arg2;\r
+                        _arg2 = data.readString();\r
+                        android.os.Bundle _arg3;\r
+                        if ((0!=data.readInt())) {\r
+                            _arg3 = android.os.Bundle.CREATOR.createFromParcel(data);\r
+                        }\r
+                        else {\r
+                            _arg3 = null;\r
+                        }\r
+                        android.os.Bundle _result = this.getSkuDetails(_arg0, _arg1, _arg2, _arg3);\r
+                        reply.writeNoException();\r
+                        if ((_result!=null)) {\r
+                            reply.writeInt(1);\r
+                            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);\r
+                        }\r
+                        else {\r
+                            reply.writeInt(0);\r
+                        }\r
+                        return true;\r
+                    }\r
+                    case TRANSACTION_getBuyIntent:\r
+                    {\r
+                        data.enforceInterface(DESCRIPTOR);\r
+                        int _arg0;\r
+                        _arg0 = data.readInt();\r
+                        java.lang.String _arg1;\r
+                        _arg1 = data.readString();\r
+                        java.lang.String _arg2;\r
+                        _arg2 = data.readString();\r
+                        java.lang.String _arg3;\r
+                        _arg3 = data.readString();\r
+                        java.lang.String _arg4;\r
+                        _arg4 = data.readString();\r
+                        android.os.Bundle _result = this.getBuyIntent(_arg0, _arg1, _arg2, _arg3, _arg4);\r
+                        reply.writeNoException();\r
+                        if ((_result!=null)) {\r
+                            reply.writeInt(1);\r
+                            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);\r
+                        }\r
+                        else {\r
+                            reply.writeInt(0);\r
+                        }\r
+                        return true;\r
+                    }\r
+                    case TRANSACTION_getPurchases:\r
+                    {\r
+                        data.enforceInterface(DESCRIPTOR);\r
+                        int _arg0;\r
+                        _arg0 = data.readInt();\r
+                        java.lang.String _arg1;\r
+                        _arg1 = data.readString();\r
+                        java.lang.String _arg2;\r
+                        _arg2 = data.readString();\r
+                        java.lang.String _arg3;\r
+                        _arg3 = data.readString();\r
+                        android.os.Bundle _result = this.getPurchases(_arg0, _arg1, _arg2, _arg3);\r
+                        reply.writeNoException();\r
+                        if ((_result!=null)) {\r
+                            reply.writeInt(1);\r
+                            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);\r
+                        }\r
+                        else {\r
+                            reply.writeInt(0);\r
+                        }\r
+                        return true;\r
+                    }\r
+                    case TRANSACTION_consumePurchase:\r
+                    {\r
+                        data.enforceInterface(DESCRIPTOR);\r
+                        int _arg0;\r
+                        _arg0 = data.readInt();\r
+                        java.lang.String _arg1;\r
+                        _arg1 = data.readString();\r
+                        java.lang.String _arg2;\r
+                        _arg2 = data.readString();\r
+                        int _result = this.consumePurchase(_arg0, _arg1, _arg2);\r
+                        reply.writeNoException();\r
+                        reply.writeInt(_result);\r
+                        return true;\r
+                    }\r
+                    case TRANSACTION_stub:\r
+                    {\r
+                        data.enforceInterface(DESCRIPTOR);\r
+                        int _arg0;\r
+                        _arg0 = data.readInt();\r
+                        java.lang.String _arg1;\r
+                        _arg1 = data.readString();\r
+                        java.lang.String _arg2;\r
+                        _arg2 = data.readString();\r
+                        int _result = this.stub(_arg0, _arg1, _arg2);\r
+                        reply.writeNoException();\r
+                        reply.writeInt(_result);\r
+                        return true;\r
+                    }\r
+                    case TRANSACTION_getBuyIntentToReplaceSkus:\r
+                    {\r
+                        data.enforceInterface(DESCRIPTOR);\r
+                        int _arg0;\r
+                        _arg0 = data.readInt();\r
+                        java.lang.String _arg1;\r
+                        _arg1 = data.readString();\r
+                        java.util.List<java.lang.String> _arg2;\r
+                        _arg2 = data.createStringArrayList();\r
+                        java.lang.String _arg3;\r
+                        _arg3 = data.readString();\r
+                        java.lang.String _arg4;\r
+                        _arg4 = data.readString();\r
+                        java.lang.String _arg5;\r
+                        _arg5 = data.readString();\r
+                        android.os.Bundle _result = this.getBuyIntentToReplaceSkus(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);\r
+                        reply.writeNoException();\r
+                        if ((_result!=null)) {\r
+                            reply.writeInt(1);\r
+                            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);\r
+                        }\r
+                        else {\r
+                            reply.writeInt(0);\r
+                        }\r
+                        return true;\r
+                    }\r
+                    case TRANSACTION_getBuyIntentExtraParams:\r
+                    {\r
+                        data.enforceInterface(DESCRIPTOR);\r
+                        int _arg0;\r
+                        _arg0 = data.readInt();\r
+                        java.lang.String _arg1;\r
+                        _arg1 = data.readString();\r
+                        java.lang.String _arg2;\r
+                        _arg2 = data.readString();\r
+                        java.lang.String _arg3;\r
+                        _arg3 = data.readString();\r
+                        java.lang.String _arg4;\r
+                        _arg4 = data.readString();\r
+                        android.os.Bundle _arg5;\r
+                        if ((0!=data.readInt())) {\r
+                            _arg5 = android.os.Bundle.CREATOR.createFromParcel(data);\r
+                        }\r
+                        else {\r
+                            _arg5 = null;\r
+                        }\r
+                        android.os.Bundle _result = this.getBuyIntentExtraParams(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);\r
+                        reply.writeNoException();\r
+                        if ((_result!=null)) {\r
+                            reply.writeInt(1);\r
+                            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);\r
+                        }\r
+                        else {\r
+                            reply.writeInt(0);\r
+                        }\r
+                        return true;\r
+                    }\r
+                    case TRANSACTION_getPurchaseHistory:\r
+                    {\r
+                        data.enforceInterface(DESCRIPTOR);\r
+                        int _arg0;\r
+                        _arg0 = data.readInt();\r
+                        java.lang.String _arg1;\r
+                        _arg1 = data.readString();\r
+                        java.lang.String _arg2;\r
+                        _arg2 = data.readString();\r
+                        java.lang.String _arg3;\r
+                        _arg3 = data.readString();\r
+                        android.os.Bundle _arg4;\r
+                        if ((0!=data.readInt())) {\r
+                            _arg4 = android.os.Bundle.CREATOR.createFromParcel(data);\r
+                        }\r
+                        else {\r
+                            _arg4 = null;\r
+                        }\r
+                        android.os.Bundle _result = this.getPurchaseHistory(_arg0, _arg1, _arg2, _arg3, _arg4);\r
+                        reply.writeNoException();\r
+                        if ((_result!=null)) {\r
+                            reply.writeInt(1);\r
+                            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);\r
+                        }\r
+                        else {\r
+                            reply.writeInt(0);\r
+                        }\r
+                        return true;\r
+                    }\r
+                    case TRANSACTION_isBillingSupportedExtraParams:\r
+                    {\r
+                        data.enforceInterface(DESCRIPTOR);\r
+                        int _arg0;\r
+                        _arg0 = data.readInt();\r
+                        java.lang.String _arg1;\r
+                        _arg1 = data.readString();\r
+                        java.lang.String _arg2;\r
+                        _arg2 = data.readString();\r
+                        android.os.Bundle _arg3;\r
+                        if ((0!=data.readInt())) {\r
+                            _arg3 = android.os.Bundle.CREATOR.createFromParcel(data);\r
+                        }\r
+                        else {\r
+                            _arg3 = null;\r
+                        }\r
+                        int _result = this.isBillingSupportedExtraParams(_arg0, _arg1, _arg2, _arg3);\r
+                        reply.writeNoException();\r
+                        reply.writeInt(_result);\r
+                        return true;\r
+                    }\r
+                }\r
+                return super.onTransact(code, data, reply, flags);\r
+            }\r
+            private static class Proxy implements com.android.vending.billing.IInAppBillingService\r
+            {\r
+                private android.os.IBinder mRemote;\r
+                Proxy(android.os.IBinder remote)\r
+                {\r
+                    mRemote = remote;\r
+                }\r
+                @Override public android.os.IBinder asBinder()\r
+                {\r
+                    return mRemote;\r
+                }\r
+                public java.lang.String getInterfaceDescriptor()\r
+                {\r
+                    return DESCRIPTOR;\r
+                }\r
+                @Override public int isBillingSupported(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException\r
+                {\r
+                    android.os.Parcel _data = android.os.Parcel.obtain();\r
+                    android.os.Parcel _reply = android.os.Parcel.obtain();\r
+                    int _result;\r
+                    try {\r
+                        _data.writeInterfaceToken(DESCRIPTOR);\r
+                        _data.writeInt(apiVersion);\r
+                        _data.writeString(packageName);\r
+                        _data.writeString(type);\r
+                        mRemote.transact(Stub.TRANSACTION_isBillingSupported, _data, _reply, 0);\r
+                        _reply.readException();\r
+                        _result = _reply.readInt();\r
+                    }\r
+                    finally {\r
+                        _reply.recycle();\r
+                        _data.recycle();\r
+                    }\r
+                    return _result;\r
+                }\r
+                /**\r
+                 * Provides details of a list of SKUs\r
+                 * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle\r
+                 * with a list JSON strings containing the productId, price, title and description.\r
+                 * This API can be called with a maximum of 20 SKUs.\r
+                 * @param apiVersion billing API version that the app is using\r
+                 * @param packageName the package name of the calling app\r
+                 * @param type of the in-app items ("inapp" for one-time purchases\r
+                 *        and "subs" for subscriptions)\r
+                 * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST"\r
+                 * @return Bundle containing the following key-value pairs\r
+                 *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes\r
+                 *                         on failures.\r
+                 *         "DETAILS_LIST" with a StringArrayList containing purchase information\r
+                 *                        in JSON format similar to:\r
+                 *                        '{ "productId" : "exampleSku",\r
+                 *                           "type" : "inapp",\r
+                 *                           "price" : "$5.00",\r
+                 *                           "price_currency": "USD",\r
+                 *                           "price_amount_micros": 5000000,\r
+                 *                           "title : "Example Title",\r
+                 *                           "description" : "This is an example description" }'\r
+                 */\r
+                @Override public android.os.Bundle getSkuDetails(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle skusBundle) throws android.os.RemoteException\r
+                {\r
+                    android.os.Parcel _data = android.os.Parcel.obtain();\r
+                    android.os.Parcel _reply = android.os.Parcel.obtain();\r
+                    android.os.Bundle _result;\r
+                    try {\r
+                        _data.writeInterfaceToken(DESCRIPTOR);\r
+                        _data.writeInt(apiVersion);\r
+                        _data.writeString(packageName);\r
+                        _data.writeString(type);\r
+                        if ((skusBundle!=null)) {\r
+                            _data.writeInt(1);\r
+                            skusBundle.writeToParcel(_data, 0);\r
+                        }\r
+                        else {\r
+                            _data.writeInt(0);\r
+                        }\r
+                        mRemote.transact(Stub.TRANSACTION_getSkuDetails, _data, _reply, 0);\r
+                        _reply.readException();\r
+                        if ((0!=_reply.readInt())) {\r
+                            _result = android.os.Bundle.CREATOR.createFromParcel(_reply);\r
+                        }\r
+                        else {\r
+                            _result = null;\r
+                        }\r
+                    }\r
+                    finally {\r
+                        _reply.recycle();\r
+                        _data.recycle();\r
+                    }\r
+                    return _result;\r
+                }\r
+                /**\r
+                 * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU,\r
+                 * the type, a unique purchase token and an optional developer payload.\r
+                 * @param apiVersion billing API version that the app is using\r
+                 * @param packageName package name of the calling app\r
+                 * @param sku the SKU of the in-app item as published in the developer console\r
+                 * @param type of the in-app item being purchased ("inapp" for one-time purchases\r
+                 *        and "subs" for subscriptions)\r
+                 * @param developerPayload optional argument to be sent back with the purchase information\r
+                 * @return Bundle containing the following key-value pairs\r
+                 *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes\r
+                 *                         on failures.\r
+                 *         "BUY_INTENT" - PendingIntent to start the purchase flow\r
+                 *\r
+                 * The Pending intent should be launched with startIntentSenderForResult. When purchase flow\r
+                 * has completed, the onActivityResult() will give a resultCode of OK or CANCELED.\r
+                 * If the purchase is successful, the result data will contain the following key-value pairs\r
+                 *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response\r
+                 *                         codes on failures.\r
+                 *         "INAPP_PURCHASE_DATA" - String in JSON format similar to\r
+                 *                                 '{"orderId":"12999763169054705758.1371079406387615",\r
+                 *                                   "packageName":"com.example.app",\r
+                 *                                   "productId":"exampleSku",\r
+                 *                                   "purchaseTime":1345678900000,\r
+                 *                                   "purchaseToken" : "122333444455555",\r
+                 *                                   "developerPayload":"example developer payload" }'\r
+                 *         "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that\r
+                 *                                  was signed with the private key of the developer\r
+                 */\r
+                @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\r
+                {\r
+                    android.os.Parcel _data = android.os.Parcel.obtain();\r
+                    android.os.Parcel _reply = android.os.Parcel.obtain();\r
+                    android.os.Bundle _result;\r
+                    try {\r
+                        _data.writeInterfaceToken(DESCRIPTOR);\r
+                        _data.writeInt(apiVersion);\r
+                        _data.writeString(packageName);\r
+                        _data.writeString(sku);\r
+                        _data.writeString(type);\r
+                        _data.writeString(developerPayload);\r
+                        mRemote.transact(Stub.TRANSACTION_getBuyIntent, _data, _reply, 0);\r
+                        _reply.readException();\r
+                        if ((0!=_reply.readInt())) {\r
+                            _result = android.os.Bundle.CREATOR.createFromParcel(_reply);\r
+                        }\r
+                        else {\r
+                            _result = null;\r
+                        }\r
+                    }\r
+                    finally {\r
+                        _reply.recycle();\r
+                        _data.recycle();\r
+                    }\r
+                    return _result;\r
+                }\r
+                /**\r
+                 * Returns the current SKUs owned by the user of the type and package name specified along with\r
+                 * purchase information and a signature of the data to be validated.\r
+                 * This will return all SKUs that have been purchased in V3 and managed items purchased using\r
+                 * V1 and V2 that have not been consumed.\r
+                 * @param apiVersion billing API version that the app is using\r
+                 * @param packageName package name of the calling app\r
+                 * @param type of the in-app items being requested ("inapp" for one-time purchases\r
+                 *        and "subs" for subscriptions)\r
+                 * @param continuationToken to be set as null for the first call, if the number of owned\r
+                 *        skus are too many, a continuationToken is returned in the response bundle.\r
+                 *        This method can be called again with the continuation token to get the next set of\r
+                 *        owned skus.\r
+                 * @return Bundle containing the following key-value pairs\r
+                 *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes\r
+                 on failures.\r
+                 *         "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs\r
+                 *         "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information\r
+                 *         "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures\r
+                 *                                      of the purchase information\r
+                 *         "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the\r
+                 *                                      next set of in-app purchases. Only set if the\r
+                 *                                      user has more owned skus than the current list.\r
+                 */\r
+                @Override public android.os.Bundle getPurchases(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken) throws android.os.RemoteException\r
+                {\r
+                    android.os.Parcel _data = android.os.Parcel.obtain();\r
+                    android.os.Parcel _reply = android.os.Parcel.obtain();\r
+                    android.os.Bundle _result;\r
+                    try {\r
+                        _data.writeInterfaceToken(DESCRIPTOR);\r
+                        _data.writeInt(apiVersion);\r
+                        _data.writeString(packageName);\r
+                        _data.writeString(type);\r
+                        _data.writeString(continuationToken);\r
+                        mRemote.transact(Stub.TRANSACTION_getPurchases, _data, _reply, 0);\r
+                        _reply.readException();\r
+                        if ((0!=_reply.readInt())) {\r
+                            _result = android.os.Bundle.CREATOR.createFromParcel(_reply);\r
+                        }\r
+                        else {\r
+                            _result = null;\r
+                        }\r
+                    }\r
+                    finally {\r
+                        _reply.recycle();\r
+                        _data.recycle();\r
+                    }\r
+                    return _result;\r
+                }\r
+                @Override public int consumePurchase(int apiVersion, java.lang.String packageName, java.lang.String purchaseToken) throws android.os.RemoteException\r
+                {\r
+                    android.os.Parcel _data = android.os.Parcel.obtain();\r
+                    android.os.Parcel _reply = android.os.Parcel.obtain();\r
+                    int _result;\r
+                    try {\r
+                        _data.writeInterfaceToken(DESCRIPTOR);\r
+                        _data.writeInt(apiVersion);\r
+                        _data.writeString(packageName);\r
+                        _data.writeString(purchaseToken);\r
+                        mRemote.transact(Stub.TRANSACTION_consumePurchase, _data, _reply, 0);\r
+                        _reply.readException();\r
+                        _result = _reply.readInt();\r
+                    }\r
+                    finally {\r
+                        _reply.recycle();\r
+                        _data.recycle();\r
+                    }\r
+                    return _result;\r
+                }\r
+                @Override public int stub(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException\r
+                {\r
+                    android.os.Parcel _data = android.os.Parcel.obtain();\r
+                    android.os.Parcel _reply = android.os.Parcel.obtain();\r
+                    int _result;\r
+                    try {\r
+                        _data.writeInterfaceToken(DESCRIPTOR);\r
+                        _data.writeInt(apiVersion);\r
+                        _data.writeString(packageName);\r
+                        _data.writeString(type);\r
+                        mRemote.transact(Stub.TRANSACTION_stub, _data, _reply, 0);\r
+                        _reply.readException();\r
+                        _result = _reply.readInt();\r
+                    }\r
+                    finally {\r
+                        _reply.recycle();\r
+                        _data.recycle();\r
+                    }\r
+                    return _result;\r
+                }\r
+                /**\r
+                 * Returns a pending intent to launch the purchase flow for upgrading or downgrading a\r
+                 * subscription. The existing owned SKU(s) should be provided along with the new SKU that\r
+                 * the user is upgrading or downgrading to.\r
+                 * @param apiVersion billing API version that the app is using, must be 5 or later\r
+                 * @param packageName package name of the calling app\r
+                 * @param oldSkus the SKU(s) that the user is upgrading or downgrading from,\r
+                 *        if null or empty this method will behave like {@link #getBuyIntent}\r
+                 * @param newSku the SKU that the user is upgrading or downgrading to\r
+                 * @param type of the item being purchased, currently must be "subs"\r
+                 * @param developerPayload optional argument to be sent back with the purchase information\r
+                 * @return Bundle containing the following key-value pairs\r
+                 *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes\r
+                 *                         on failures.\r
+                 *         "BUY_INTENT" - PendingIntent to start the purchase flow\r
+                 *\r
+                 * The Pending intent should be launched with startIntentSenderForResult. When purchase flow\r
+                 * has completed, the onActivityResult() will give a resultCode of OK or CANCELED.\r
+                 * If the purchase is successful, the result data will contain the following key-value pairs\r
+                 *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response\r
+                 *                         codes on failures.\r
+                 *         "INAPP_PURCHASE_DATA" - String in JSON format similar to\r
+                 *                                 '{"orderId":"12999763169054705758.1371079406387615",\r
+                 *                                   "packageName":"com.example.app",\r
+                 *                                   "productId":"exampleSku",\r
+                 *                                   "purchaseTime":1345678900000,\r
+                 *                                   "purchaseToken" : "122333444455555",\r
+                 *                                   "developerPayload":"example developer payload" }'\r
+                 *         "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that\r
+                 *                                  was signed with the private key of the developer\r
+                 */\r
+                @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\r
+                {\r
+                    android.os.Parcel _data = android.os.Parcel.obtain();\r
+                    android.os.Parcel _reply = android.os.Parcel.obtain();\r
+                    android.os.Bundle _result;\r
+                    try {\r
+                        _data.writeInterfaceToken(DESCRIPTOR);\r
+                        _data.writeInt(apiVersion);\r
+                        _data.writeString(packageName);\r
+                        _data.writeStringList(oldSkus);\r
+                        _data.writeString(newSku);\r
+                        _data.writeString(type);\r
+                        _data.writeString(developerPayload);\r
+                        mRemote.transact(Stub.TRANSACTION_getBuyIntentToReplaceSkus, _data, _reply, 0);\r
+                        _reply.readException();\r
+                        if ((0!=_reply.readInt())) {\r
+                            _result = android.os.Bundle.CREATOR.createFromParcel(_reply);\r
+                        }\r
+                        else {\r
+                            _result = null;\r
+                        }\r
+                    }\r
+                    finally {\r
+                        _reply.recycle();\r
+                        _data.recycle();\r
+                    }\r
+                    return _result;\r
+                }\r
+                /**\r
+                 * Returns a pending intent to launch the purchase flow for an in-app item. This method is\r
+                 * a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams}\r
+                 * parameter. This parameter is a Bundle of optional keys and values that affect the\r
+                 * operation of the method.\r
+                 * @param apiVersion billing API version that the app is using, must be 6 or later\r
+                 * @param packageName package name of the calling app\r
+                 * @param sku the SKU of the in-app item as published in the developer console\r
+                 * @param type of the in-app item being purchased ("inapp" for one-time purchases\r
+                 *        and "subs" for subscriptions)\r
+                 * @param developerPayload optional argument to be sent back with the purchase information\r
+                 * @extraParams a Bundle with the following optional keys:\r
+                 *        "skusToReplace" - List<String> - an optional list of SKUs that the user is\r
+                 *                          upgrading or downgrading from.\r
+                 *                          Pass this field if the purchase is upgrading or downgrading\r
+                 *                          existing subscriptions.\r
+                 *                          The specified SKUs are replaced with the SKUs that the user is\r
+                 *                          purchasing. Google Play replaces the specified SKUs at the start of\r
+                 *                          the next billing cycle.\r
+                 * "replaceSkusProration" - Boolean - whether the user should be credited for any unused\r
+                 *                          subscription time on the SKUs they are upgrading or downgrading.\r
+                 *                          If you set this field to true, Google Play swaps out the old SKUs\r
+                 *                          and credits the user with the unused value of their subscription\r
+                 *                          time on a pro-rated basis.\r
+                 *                          Google Play applies this credit to the new subscription, and does\r
+                 *                          not begin billing the user for the new subscription until after\r
+                 *                          the credit is used up.\r
+                 *                          If you set this field to false, the user does not receive credit for\r
+                 *                          any unused subscription time and the recurrence date does not\r
+                 *                          change.\r
+                 *                          Default value is true. Ignored if you do not pass skusToReplace.\r
+                 *            "accountId" - String - an optional obfuscated string that is uniquely\r
+                 *                          associated with the user's account in your app.\r
+                 *                          If you pass this value, Google Play can use it to detect irregular\r
+                 *                          activity, such as many devices making purchases on the same\r
+                 *                          account in a short period of time.\r
+                 *                          Do not use the developer ID or the user's Google ID for this field.\r
+                 *                          In addition, this field should not contain the user's ID in\r
+                 *                          cleartext.\r
+                 *                          We recommend that you use a one-way hash to generate a string from\r
+                 *                          the user's ID, and store the hashed string in this field.\r
+                 *                   "vr" - Boolean - an optional flag indicating whether the returned intent\r
+                 *                          should start a VR purchase flow. The apiVersion must also be 7 or\r
+                 *                          later to use this flag.\r
+                 */\r
+                @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\r
+                {\r
+                    android.os.Parcel _data = android.os.Parcel.obtain();\r
+                    android.os.Parcel _reply = android.os.Parcel.obtain();\r
+                    android.os.Bundle _result;\r
+                    try {\r
+                        _data.writeInterfaceToken(DESCRIPTOR);\r
+                        _data.writeInt(apiVersion);\r
+                        _data.writeString(packageName);\r
+                        _data.writeString(sku);\r
+                        _data.writeString(type);\r
+                        _data.writeString(developerPayload);\r
+                        if ((extraParams!=null)) {\r
+                            _data.writeInt(1);\r
+                            extraParams.writeToParcel(_data, 0);\r
+                        }\r
+                        else {\r
+                            _data.writeInt(0);\r
+                        }\r
+                        mRemote.transact(Stub.TRANSACTION_getBuyIntentExtraParams, _data, _reply, 0);\r
+                        _reply.readException();\r
+                        if ((0!=_reply.readInt())) {\r
+                            _result = android.os.Bundle.CREATOR.createFromParcel(_reply);\r
+                        }\r
+                        else {\r
+                            _result = null;\r
+                        }\r
+                    }\r
+                    finally {\r
+                        _reply.recycle();\r
+                        _data.recycle();\r
+                    }\r
+                    return _result;\r
+                }\r
+                /**\r
+                 * Returns the most recent purchase made by the user for each SKU, even if that purchase is\r
+                 * expired, canceled, or consumed.\r
+                 * @param apiVersion billing API version that the app is using, must be 6 or later\r
+                 * @param packageName package name of the calling app\r
+                 * @param type of the in-app items being requested ("inapp" for one-time purchases\r
+                 *        and "subs" for subscriptions)\r
+                 * @param continuationToken to be set as null for the first call, if the number of owned\r
+                 *        skus is too large, a continuationToken is returned in the response bundle.\r
+                 *        This method can be called again with the continuation token to get the next set of\r
+                 *        owned skus.\r
+                 * @param extraParams a Bundle with extra params that would be appended into http request\r
+                 *        query string. Not used at this moment. Reserved for future functionality.\r
+                 * @return Bundle containing the following key-value pairs\r
+                 *         "RESPONSE_CODE" with int value: RESULT_OK(0) if success,\r
+                 *         {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures.\r
+                 *\r
+                 *         "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs\r
+                 *         "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information\r
+                 *         "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> containing the signatures\r
+                 *                                      of the purchase information\r
+                 *         "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the\r
+                 *                                      next set of in-app purchases. Only set if the\r
+                 *                                      user has more owned skus than the current list.\r
+                 */\r
+                @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\r
+                {\r
+                    android.os.Parcel _data = android.os.Parcel.obtain();\r
+                    android.os.Parcel _reply = android.os.Parcel.obtain();\r
+                    android.os.Bundle _result;\r
+                    try {\r
+                        _data.writeInterfaceToken(DESCRIPTOR);\r
+                        _data.writeInt(apiVersion);\r
+                        _data.writeString(packageName);\r
+                        _data.writeString(type);\r
+                        _data.writeString(continuationToken);\r
+                        if ((extraParams!=null)) {\r
+                            _data.writeInt(1);\r
+                            extraParams.writeToParcel(_data, 0);\r
+                        }\r
+                        else {\r
+                            _data.writeInt(0);\r
+                        }\r
+                        mRemote.transact(Stub.TRANSACTION_getPurchaseHistory, _data, _reply, 0);\r
+                        _reply.readException();\r
+                        if ((0!=_reply.readInt())) {\r
+                            _result = android.os.Bundle.CREATOR.createFromParcel(_reply);\r
+                        }\r
+                        else {\r
+                            _result = null;\r
+                        }\r
+                    }\r
+                    finally {\r
+                        _reply.recycle();\r
+                        _data.recycle();\r
+                    }\r
+                    return _result;\r
+                }\r
+                @Override public int isBillingSupportedExtraParams(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle extraParams) throws android.os.RemoteException\r
+                {\r
+                    android.os.Parcel _data = android.os.Parcel.obtain();\r
+                    android.os.Parcel _reply = android.os.Parcel.obtain();\r
+                    int _result;\r
+                    try {\r
+                        _data.writeInterfaceToken(DESCRIPTOR);\r
+                        _data.writeInt(apiVersion);\r
+                        _data.writeString(packageName);\r
+                        _data.writeString(type);\r
+                        if ((extraParams!=null)) {\r
+                            _data.writeInt(1);\r
+                            extraParams.writeToParcel(_data, 0);\r
+                        }\r
+                        else {\r
+                            _data.writeInt(0);\r
+                        }\r
+                        mRemote.transact(Stub.TRANSACTION_isBillingSupportedExtraParams, _data, _reply, 0);\r
+                        _reply.readException();\r
+                        _result = _reply.readInt();\r
+                    }\r
+                    finally {\r
+                        _reply.recycle();\r
+                        _data.recycle();\r
+                    }\r
+                    return _result;\r
+                }\r
+            }\r
+            static final int TRANSACTION_isBillingSupported = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);\r
+            static final int TRANSACTION_getSkuDetails = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);\r
+            static final int TRANSACTION_getBuyIntent = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);\r
+            static final int TRANSACTION_getPurchases = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);\r
+            static final int TRANSACTION_consumePurchase = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);\r
+            static final int TRANSACTION_stub = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);\r
+            static final int TRANSACTION_getBuyIntentToReplaceSkus = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);\r
+            static final int TRANSACTION_getBuyIntentExtraParams = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);\r
+            static final int TRANSACTION_getPurchaseHistory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8);\r
+            static final int TRANSACTION_isBillingSupportedExtraParams = (android.os.IBinder.FIRST_CALL_TRANSACTION + 9);\r
+        }\r
+        public int isBillingSupported(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException;\r
+        /**\r
+         * Provides details of a list of SKUs\r
+         * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle\r
+         * with a list JSON strings containing the productId, price, title and description.\r
+         * This API can be called with a maximum of 20 SKUs.\r
+         * @param apiVersion billing API version that the app is using\r
+         * @param packageName the package name of the calling app\r
+         * @param type of the in-app items ("inapp" for one-time purchases\r
+         *        and "subs" for subscriptions)\r
+         * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST"\r
+         * @return Bundle containing the following key-value pairs\r
+         *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes\r
+         *                         on failures.\r
+         *         "DETAILS_LIST" with a StringArrayList containing purchase information\r
+         *                        in JSON format similar to:\r
+         *                        '{ "productId" : "exampleSku",\r
+         *                           "type" : "inapp",\r
+         *                           "price" : "$5.00",\r
+         *                           "price_currency": "USD",\r
+         *                           "price_amount_micros": 5000000,\r
+         *                           "title : "Example Title",\r
+         *                           "description" : "This is an example description" }'\r
+         */\r
+        public android.os.Bundle getSkuDetails(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle skusBundle) throws android.os.RemoteException;\r
+        /**\r
+         * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU,\r
+         * the type, a unique purchase token and an optional developer payload.\r
+         * @param apiVersion billing API version that the app is using\r
+         * @param packageName package name of the calling app\r
+         * @param sku the SKU of the in-app item as published in the developer console\r
+         * @param type of the in-app item being purchased ("inapp" for one-time purchases\r
+         *        and "subs" for subscriptions)\r
+         * @param developerPayload optional argument to be sent back with the purchase information\r
+         * @return Bundle containing the following key-value pairs\r
+         *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes\r
+         *                         on failures.\r
+         *         "BUY_INTENT" - PendingIntent to start the purchase flow\r
+         *\r
+         * The Pending intent should be launched with startIntentSenderForResult. When purchase flow\r
+         * has completed, the onActivityResult() will give a resultCode of OK or CANCELED.\r
+         * If the purchase is successful, the result data will contain the following key-value pairs\r
+         *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response\r
+         *                         codes on failures.\r
+         *         "INAPP_PURCHASE_DATA" - String in JSON format similar to\r
+         *                                 '{"orderId":"12999763169054705758.1371079406387615",\r
+         *                                   "packageName":"com.example.app",\r
+         *                                   "productId":"exampleSku",\r
+         *                                   "purchaseTime":1345678900000,\r
+         *                                   "purchaseToken" : "122333444455555",\r
+         *                                   "developerPayload":"example developer payload" }'\r
+         *         "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that\r
+         *                                  was signed with the private key of the developer\r
+         */\r
+        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;\r
+        /**\r
+         * Returns the current SKUs owned by the user of the type and package name specified along with\r
+         * purchase information and a signature of the data to be validated.\r
+         * This will return all SKUs that have been purchased in V3 and managed items purchased using\r
+         * V1 and V2 that have not been consumed.\r
+         * @param apiVersion billing API version that the app is using\r
+         * @param packageName package name of the calling app\r
+         * @param type of the in-app items being requested ("inapp" for one-time purchases\r
+         *        and "subs" for subscriptions)\r
+         * @param continuationToken to be set as null for the first call, if the number of owned\r
+         *        skus are too many, a continuationToken is returned in the response bundle.\r
+         *        This method can be called again with the continuation token to get the next set of\r
+         *        owned skus.\r
+         * @return Bundle containing the following key-value pairs\r
+         *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes\r
+         on failures.\r
+         *         "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs\r
+         *         "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information\r
+         *         "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures\r
+         *                                      of the purchase information\r
+         *         "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the\r
+         *                                      next set of in-app purchases. Only set if the\r
+         *                                      user has more owned skus than the current list.\r
+         */\r
+        public android.os.Bundle getPurchases(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken) throws android.os.RemoteException;\r
+        public int consumePurchase(int apiVersion, java.lang.String packageName, java.lang.String purchaseToken) throws android.os.RemoteException;\r
+        public int stub(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException;\r
+        /**\r
+         * Returns a pending intent to launch the purchase flow for upgrading or downgrading a\r
+         * subscription. The existing owned SKU(s) should be provided along with the new SKU that\r
+         * the user is upgrading or downgrading to.\r
+         * @param apiVersion billing API version that the app is using, must be 5 or later\r
+         * @param packageName package name of the calling app\r
+         * @param oldSkus the SKU(s) that the user is upgrading or downgrading from,\r
+         *        if null or empty this method will behave like {@link #getBuyIntent}\r
+         * @param newSku the SKU that the user is upgrading or downgrading to\r
+         * @param type of the item being purchased, currently must be "subs"\r
+         * @param developerPayload optional argument to be sent back with the purchase information\r
+         * @return Bundle containing the following key-value pairs\r
+         *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes\r
+         *                         on failures.\r
+         *         "BUY_INTENT" - PendingIntent to start the purchase flow\r
+         *\r
+         * The Pending intent should be launched with startIntentSenderForResult. When purchase flow\r
+         * has completed, the onActivityResult() will give a resultCode of OK or CANCELED.\r
+         * If the purchase is successful, the result data will contain the following key-value pairs\r
+         *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response\r
+         *                         codes on failures.\r
+         *         "INAPP_PURCHASE_DATA" - String in JSON format similar to\r
+         *                                 '{"orderId":"12999763169054705758.1371079406387615",\r
+         *                                   "packageName":"com.example.app",\r
+         *                                   "productId":"exampleSku",\r
+         *                                   "purchaseTime":1345678900000,\r
+         *                                   "purchaseToken" : "122333444455555",\r
+         *                                   "developerPayload":"example developer payload" }'\r
+         *         "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that\r
+         *                                  was signed with the private key of the developer\r
+         */\r
+        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;\r
+        /**\r
+         * Returns a pending intent to launch the purchase flow for an in-app item. This method is\r
+         * a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams}\r
+         * parameter. This parameter is a Bundle of optional keys and values that affect the\r
+         * operation of the method.\r
+         * @param apiVersion billing API version that the app is using, must be 6 or later\r
+         * @param packageName package name of the calling app\r
+         * @param sku the SKU of the in-app item as published in the developer console\r
+         * @param type of the in-app item being purchased ("inapp" for one-time purchases\r
+         *        and "subs" for subscriptions)\r
+         * @param developerPayload optional argument to be sent back with the purchase information\r
+         * @extraParams a Bundle with the following optional keys:\r
+         *        "skusToReplace" - List<String> - an optional list of SKUs that the user is\r
+         *                          upgrading or downgrading from.\r
+         *                          Pass this field if the purchase is upgrading or downgrading\r
+         *                          existing subscriptions.\r
+         *                          The specified SKUs are replaced with the SKUs that the user is\r
+         *                          purchasing. Google Play replaces the specified SKUs at the start of\r
+         *                          the next billing cycle.\r
+         * "replaceSkusProration" - Boolean - whether the user should be credited for any unused\r
+         *                          subscription time on the SKUs they are upgrading or downgrading.\r
+         *                          If you set this field to true, Google Play swaps out the old SKUs\r
+         *                          and credits the user with the unused value of their subscription\r
+         *                          time on a pro-rated basis.\r
+         *                          Google Play applies this credit to the new subscription, and does\r
+         *                          not begin billing the user for the new subscription until after\r
+         *                          the credit is used up.\r
+         *                          If you set this field to false, the user does not receive credit for\r
+         *                          any unused subscription time and the recurrence date does not\r
+         *                          change.\r
+         *                          Default value is true. Ignored if you do not pass skusToReplace.\r
+         *            "accountId" - String - an optional obfuscated string that is uniquely\r
+         *                          associated with the user's account in your app.\r
+         *                          If you pass this value, Google Play can use it to detect irregular\r
+         *                          activity, such as many devices making purchases on the same\r
+         *                          account in a short period of time.\r
+         *                          Do not use the developer ID or the user's Google ID for this field.\r
+         *                          In addition, this field should not contain the user's ID in\r
+         *                          cleartext.\r
+         *                          We recommend that you use a one-way hash to generate a string from\r
+         *                          the user's ID, and store the hashed string in this field.\r
+         *                   "vr" - Boolean - an optional flag indicating whether the returned intent\r
+         *                          should start a VR purchase flow. The apiVersion must also be 7 or\r
+         *                          later to use this flag.\r
+         */\r
+        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;\r
+        /**\r
+         * Returns the most recent purchase made by the user for each SKU, even if that purchase is\r
+         * expired, canceled, or consumed.\r
+         * @param apiVersion billing API version that the app is using, must be 6 or later\r
+         * @param packageName package name of the calling app\r
+         * @param type of the in-app items being requested ("inapp" for one-time purchases\r
+         *        and "subs" for subscriptions)\r
+         * @param continuationToken to be set as null for the first call, if the number of owned\r
+         *        skus is too large, a continuationToken is returned in the response bundle.\r
+         *        This method can be called again with the continuation token to get the next set of\r
+         *        owned skus.\r
+         * @param extraParams a Bundle with extra params that would be appended into http request\r
+         *        query string. Not used at this moment. Reserved for future functionality.\r
+         * @return Bundle containing the following key-value pairs\r
+         *         "RESPONSE_CODE" with int value: RESULT_OK(0) if success,\r
+         *         {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures.\r
+         *\r
+         *         "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs\r
+         *         "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information\r
+         *         "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> containing the signatures\r
+         *                                      of the purchase information\r
+         *         "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the\r
+         *                                      next set of in-app purchases. Only set if the\r
+         *                                      user has more owned skus than the current list.\r
+         */\r
+        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;\r
+        public int isBillingSupportedExtraParams(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle extraParams) throws android.os.RemoteException;\r
+    }\r
diff --git a/extras/AudioPluginHost/Builds/Android/app/src/main/java/com/roli/juce/pluginhost/AudioPluginHost.java b/extras/AudioPluginHost/Builds/Android/app/src/main/java/com/roli/juce/pluginhost/AudioPluginHost.java
new file mode 100644 (file)
index 0000000..11134d2
--- /dev/null
@@ -0,0 +1,2782 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   The code included in this file is provided under the terms of the ISC license\r
+   http://www.isc.org/downloads/software-support-policy/isc-license. Permission\r
+   To use, copy, modify, and/or distribute this software for any purpose with or\r
+   without fee is hereby granted provided that the above copyright notice and\r
+   this permission notice appear in all copies.\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+package com.roli.juce.pluginhost;\r
+\r
+import android.app.Activity;\r
+import android.app.AlertDialog;\r
+import android.content.DialogInterface;\r
+import android.content.Context;\r
+import android.content.Intent;\r
+import android.content.res.Configuration;\r
+import android.content.pm.PackageInfo;\r
+import android.content.pm.PackageManager;\r
+import android.net.http.SslError;\r
+import android.net.Uri;\r
+import android.os.Bundle;\r
+import android.os.Looper;\r
+import android.os.Handler;\r
+import android.os.Message;\r
+import android.os.ParcelUuid;\r
+import android.os.Environment;\r
+import android.view.*;\r
+import android.view.inputmethod.BaseInputConnection;\r
+import android.view.inputmethod.EditorInfo;\r
+import android.view.inputmethod.InputConnection;\r
+import android.view.inputmethod.InputMethodManager;\r
+import android.graphics.*;\r
+import android.text.ClipboardManager;\r
+import android.text.InputType;\r
+import android.util.DisplayMetrics;\r
+import android.util.Log;\r
+import android.util.Pair;\r
+import android.webkit.SslErrorHandler;\r
+import android.webkit.WebChromeClient;\r
+import android.webkit.WebResourceError;\r
+import android.webkit.WebResourceRequest;\r
+import android.webkit.WebResourceResponse;\r
+import android.webkit.WebView;\r
+import android.webkit.WebViewClient;\r
+import java.lang.Runnable;\r
+import java.lang.ref.WeakReference;\r
+import java.lang.reflect.*;\r
+import java.util.*;\r
+import java.io.*;\r
+import java.net.URL;\r
+import java.net.HttpURLConnection;\r
+import android.media.AudioManager;\r
+import android.Manifest;\r
+import java.util.concurrent.CancellationException;\r
+import java.util.concurrent.Future;\r
+import java.util.concurrent.Executors;\r
+import java.util.concurrent.ExecutorService;\r
+import java.util.concurrent.ExecutionException;\r
+import java.util.concurrent.TimeUnit;\r
+import java.util.concurrent.Callable;\r
+import java.util.concurrent.TimeoutException;\r
+import java.util.concurrent.locks.ReentrantLock;\r
+import java.util.concurrent.atomic.*;\r
+\r
+import android.media.midi.*;\r
+import android.bluetooth.*;\r
+import android.bluetooth.le.*;\r
+\r
+\r
+//==============================================================================\r
+public class AudioPluginHost   extends Activity\r
+{\r
+    //==============================================================================\r
+    static\r
+    {\r
+        System.loadLibrary ("juce_jni");\r
+    }\r
+\r
+    //==============================================================================\r
+    public boolean isPermissionDeclaredInManifest (int permissionID)\r
+    {\r
+        String permissionToCheck = getAndroidPermissionName(permissionID);\r
+\r
+        try\r
+        {\r
+            PackageInfo info = getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS);\r
+\r
+            if (info.requestedPermissions != null)\r
+                for (String permission : info.requestedPermissions)\r
+                    if (permission.equals (permissionToCheck))\r
+                        return true;\r
+        }\r
+        catch (PackageManager.NameNotFoundException e)\r
+        {\r
+            Log.d ("JUCE", "isPermissionDeclaredInManifest: PackageManager.NameNotFoundException = " + e.toString());\r
+        }\r
+\r
+        Log.d ("JUCE", "isPermissionDeclaredInManifest: could not find requested permission " + permissionToCheck);\r
+        return false;\r
+    }\r
+\r
+    //==============================================================================\r
+    // these have to match the values of enum PermissionID in C++ class RuntimePermissions:\r
+    private static final int JUCE_PERMISSIONS_RECORD_AUDIO = 1;\r
+    private static final int JUCE_PERMISSIONS_BLUETOOTH_MIDI = 2;\r
+    private static final int JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE = 3;\r
+    private static final int JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 4;\r
+\r
+    private static String getAndroidPermissionName (int permissionID)\r
+    {\r
+        switch (permissionID)\r
+        {\r
+            case JUCE_PERMISSIONS_RECORD_AUDIO:           return Manifest.permission.RECORD_AUDIO;\r
+            case JUCE_PERMISSIONS_BLUETOOTH_MIDI:         return Manifest.permission.ACCESS_COARSE_LOCATION;\r
+                                                          // use string value as this is not defined in SDKs < 16\r
+            case JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE:  return "android.permission.READ_EXTERNAL_STORAGE";\r
+            case JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE: return Manifest.permission.WRITE_EXTERNAL_STORAGE;\r
+        }\r
+\r
+        // unknown permission ID!\r
+        assert false;\r
+        return new String();\r
+    }\r
+\r
+    public boolean isPermissionGranted (int permissionID)\r
+    {\r
+        return getApplicationContext().checkCallingOrSelfPermission (getAndroidPermissionName (permissionID)) == PackageManager.PERMISSION_GRANTED;\r
+    }\r
+\r
+    private Map<Integer, Long> permissionCallbackPtrMap;\r
+\r
+    public void requestRuntimePermission (int permissionID, long ptrToCallback)\r
+    {\r
+        String permissionName = getAndroidPermissionName (permissionID);\r
+\r
+        if (getApplicationContext().checkCallingOrSelfPermission (permissionName) != PackageManager.PERMISSION_GRANTED)\r
+        {\r
+            // remember callbackPtr, request permissions, and let onRequestPermissionResult call callback asynchronously\r
+            permissionCallbackPtrMap.put (permissionID, ptrToCallback);\r
+            requestPermissionsCompat (new String[]{permissionName}, permissionID);\r
+        }\r
+        else\r
+        {\r
+            // permissions were already granted before, we can call callback directly\r
+            androidRuntimePermissionsCallback (true, ptrToCallback);\r
+        }\r
+    }\r
+\r
+    private native void androidRuntimePermissionsCallback (boolean permissionWasGranted, long ptrToCallback);\r
+\r
+    @Override\r
+    public void onRequestPermissionsResult (int permissionID, String permissions[], int[] grantResults)\r
+    {\r
+        boolean permissionsGranted = (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED);\r
+\r
+        if (! permissionsGranted)\r
+            Log.d ("JUCE", "onRequestPermissionsResult: runtime permission was DENIED: " + getAndroidPermissionName (permissionID));\r
+\r
+        Long ptrToCallback = permissionCallbackPtrMap.get (permissionID);\r
+        permissionCallbackPtrMap.remove (permissionID);\r
+        androidRuntimePermissionsCallback (permissionsGranted, ptrToCallback);\r
+    }\r
+\r
+    //==============================================================================\r
+    public interface JuceMidiPort\r
+    {\r
+        boolean isInputPort();\r
+\r
+        // start, stop does nothing on an output port\r
+        void start();\r
+        void stop();\r
+\r
+        void close();\r
+\r
+        // send will do nothing on an input port\r
+        void sendMidi (byte[] msg, int offset, int count);\r
+    }\r
+\r
+    //==============================================================================\r
+    //==============================================================================\r
+    public class BluetoothManager extends ScanCallback\r
+    {\r
+        BluetoothManager()\r
+        {\r
+        }\r
+\r
+        public String[] getMidiBluetoothAddresses()\r
+        {\r
+            return bluetoothMidiDevices.toArray (new String[bluetoothMidiDevices.size()]);\r
+        }\r
+\r
+        public String getHumanReadableStringForBluetoothAddress (String address)\r
+        {\r
+            BluetoothDevice btDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice (address);\r
+            return btDevice.getName();\r
+        }\r
+\r
+        public int getBluetoothDeviceStatus (String address)\r
+        {\r
+            return getAndroidMidiDeviceManager().getBluetoothDeviceStatus (address);\r
+        }\r
+\r
+        public void startStopScan (boolean shouldStart)\r
+        {\r
+            BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();\r
+\r
+            if (bluetoothAdapter == null)\r
+            {\r
+                Log.d ("JUCE", "BluetoothManager error: could not get default Bluetooth adapter");\r
+                return;\r
+            }\r
+\r
+            BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();\r
+\r
+            if (bluetoothLeScanner == null)\r
+            {\r
+                Log.d ("JUCE", "BluetoothManager error: could not get Bluetooth LE scanner");\r
+                return;\r
+            }\r
+\r
+            if (shouldStart)\r
+            {\r
+                ScanFilter.Builder scanFilterBuilder = new ScanFilter.Builder();\r
+                scanFilterBuilder.setServiceUuid (ParcelUuid.fromString (bluetoothLEMidiServiceUUID));\r
+\r
+                ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder();\r
+                scanSettingsBuilder.setCallbackType (ScanSettings.CALLBACK_TYPE_ALL_MATCHES)\r
+                                   .setScanMode (ScanSettings.SCAN_MODE_LOW_POWER)\r
+                                   .setScanMode (ScanSettings.MATCH_MODE_STICKY);\r
+\r
+                bluetoothLeScanner.startScan (Arrays.asList (scanFilterBuilder.build()),\r
+                                              scanSettingsBuilder.build(),\r
+                                              this);\r
+            }\r
+            else\r
+            {\r
+                bluetoothLeScanner.stopScan (this);\r
+            }\r
+        }\r
+\r
+        public boolean pairBluetoothMidiDevice(String address)\r
+        {\r
+            BluetoothDevice btDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice (address);\r
+\r
+            if (btDevice == null)\r
+            {\r
+                Log.d ("JUCE", "failed to create buletooth device from address");\r
+                return false;\r
+            }\r
+\r
+            return getAndroidMidiDeviceManager().pairBluetoothDevice (btDevice);\r
+        }\r
+\r
+        public void unpairBluetoothMidiDevice (String address)\r
+        {\r
+            getAndroidMidiDeviceManager().unpairBluetoothDevice (address);\r
+        }\r
+\r
+        public void onScanFailed (int errorCode)\r
+        {\r
+        }\r
+\r
+        public void onScanResult (int callbackType, ScanResult result)\r
+        {\r
+            if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES\r
+                 || callbackType == ScanSettings.CALLBACK_TYPE_FIRST_MATCH)\r
+            {\r
+                BluetoothDevice device = result.getDevice();\r
+\r
+                if (device != null)\r
+                    bluetoothMidiDevices.add (device.getAddress());\r
+            }\r
+\r
+            if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST)\r
+            {\r
+                Log.d ("JUCE", "ScanSettings.CALLBACK_TYPE_MATCH_LOST");\r
+                BluetoothDevice device = result.getDevice();\r
+\r
+                if (device != null)\r
+                {\r
+                    bluetoothMidiDevices.remove (device.getAddress());\r
+                    unpairBluetoothMidiDevice (device.getAddress());\r
+                }\r
+            }\r
+        }\r
+\r
+        public void onBatchScanResults (List<ScanResult> results)\r
+        {\r
+            for (ScanResult result : results)\r
+                onScanResult (ScanSettings.CALLBACK_TYPE_ALL_MATCHES, result);\r
+        }\r
+\r
+        private BluetoothLeScanner scanner;\r
+        private static final String bluetoothLEMidiServiceUUID = "03B80E5A-EDE8-4B33-A751-6CE34EC4C700";\r
+\r
+        private HashSet<String> bluetoothMidiDevices = new HashSet<String>();\r
+    }\r
+\r
+    public static class JuceMidiInputPort extends MidiReceiver implements JuceMidiPort\r
+    {\r
+        private native void handleReceive (long host, byte[] msg, int offset, int count, long timestamp);\r
+\r
+        public JuceMidiInputPort (MidiDeviceManager mm, MidiOutputPort actualPort, MidiPortPath portPathToUse, long hostToUse)\r
+        {\r
+            owner = mm;\r
+            androidPort = actualPort;\r
+            portPath = portPathToUse;\r
+            juceHost = hostToUse;\r
+            isConnected = false;\r
+        }\r
+\r
+        @Override\r
+        protected void finalize() throws Throwable\r
+        {\r
+            close();\r
+            super.finalize();\r
+        }\r
+\r
+        @Override\r
+        public boolean isInputPort()\r
+        {\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public void start()\r
+        {\r
+            if (owner != null && androidPort != null && ! isConnected) {\r
+                androidPort.connect(this);\r
+                isConnected = true;\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void stop()\r
+        {\r
+            if (owner != null && androidPort != null && isConnected) {\r
+                androidPort.disconnect(this);\r
+                isConnected = false;\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void close()\r
+        {\r
+            if (androidPort != null) {\r
+                try {\r
+                    androidPort.close();\r
+                } catch (IOException exception) {\r
+                    Log.d("JUCE", "IO Exception while closing port");\r
+                }\r
+            }\r
+\r
+            if (owner != null)\r
+                owner.removePort (portPath);\r
+\r
+            owner = null;\r
+            androidPort = null;\r
+        }\r
+\r
+        @Override\r
+        public void onSend (byte[] msg, int offset, int count, long timestamp)\r
+        {\r
+            if (count > 0)\r
+                handleReceive (juceHost, msg, offset, count, timestamp);\r
+        }\r
+\r
+        @Override\r
+        public void onFlush()\r
+        {}\r
+\r
+        @Override\r
+        public void sendMidi (byte[] msg, int offset, int count)\r
+        {\r
+        }\r
+\r
+        MidiDeviceManager owner;\r
+        MidiOutputPort androidPort;\r
+        MidiPortPath portPath;\r
+        long juceHost;\r
+        boolean isConnected;\r
+    }\r
+\r
+    public static class JuceMidiOutputPort implements JuceMidiPort\r
+    {\r
+        public JuceMidiOutputPort (MidiDeviceManager mm, MidiInputPort actualPort, MidiPortPath portPathToUse)\r
+        {\r
+            owner = mm;\r
+            androidPort = actualPort;\r
+            portPath = portPathToUse;\r
+        }\r
+\r
+        @Override\r
+        protected void finalize() throws Throwable\r
+        {\r
+            close();\r
+            super.finalize();\r
+        }\r
+\r
+        @Override\r
+        public boolean isInputPort()\r
+        {\r
+            return false;\r
+        }\r
+\r
+        @Override\r
+        public void start()\r
+        {\r
+        }\r
+\r
+        @Override\r
+        public void stop()\r
+        {\r
+        }\r
+\r
+        @Override\r
+        public void sendMidi (byte[] msg, int offset, int count)\r
+        {\r
+            if (androidPort != null)\r
+            {\r
+                try {\r
+                    androidPort.send(msg, offset, count);\r
+                } catch (IOException exception)\r
+                {\r
+                    Log.d ("JUCE", "send midi had IO exception");\r
+                }\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void close()\r
+        {\r
+            if (androidPort != null) {\r
+                try {\r
+                    androidPort.close();\r
+                } catch (IOException exception) {\r
+                    Log.d("JUCE", "IO Exception while closing port");\r
+                }\r
+            }\r
+\r
+            if (owner != null)\r
+                owner.removePort (portPath);\r
+\r
+            owner = null;\r
+            androidPort = null;\r
+        }\r
+\r
+        MidiDeviceManager owner;\r
+        MidiInputPort androidPort;\r
+        MidiPortPath portPath;\r
+    }\r
+\r
+    private static class MidiPortPath extends Object\r
+    {\r
+        public MidiPortPath (int deviceIdToUse, boolean direction, int androidIndex)\r
+        {\r
+            deviceId = deviceIdToUse;\r
+            isInput = direction;\r
+            portIndex = androidIndex;\r
+\r
+        }\r
+\r
+        public int deviceId;\r
+        public int portIndex;\r
+        public boolean isInput;\r
+\r
+        @Override\r
+        public int hashCode()\r
+        {\r
+            Integer i = new Integer ((deviceId * 128) + (portIndex < 128 ? portIndex : 127));\r
+            return i.hashCode() * (isInput ? -1 : 1);\r
+        }\r
+\r
+        @Override\r
+        public boolean equals (Object obj)\r
+        {\r
+            if (obj == null)\r
+                return false;\r
+\r
+            if (getClass() != obj.getClass())\r
+                return false;\r
+\r
+            MidiPortPath other = (MidiPortPath) obj;\r
+            return (portIndex == other.portIndex && isInput == other.isInput && deviceId == other.deviceId);\r
+        }\r
+    }\r
+\r
+    //==============================================================================\r
+    public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener\r
+    {\r
+        //==============================================================================\r
+        private class DummyBluetoothGattCallback extends BluetoothGattCallback\r
+        {\r
+            public DummyBluetoothGattCallback (MidiDeviceManager mm)\r
+            {\r
+                super();\r
+                owner = mm;\r
+            }\r
+\r
+            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState)\r
+            {\r
+                if (newState == BluetoothProfile.STATE_CONNECTED)\r
+                {\r
+                    gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);\r
+                    owner.pairBluetoothDeviceStepTwo (gatt.getDevice());\r
+                }\r
+            }\r
+            public void onServicesDiscovered(BluetoothGatt gatt, int status) {}\r
+            public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {}\r
+            public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {}\r
+            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {}\r
+            public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {}\r
+            public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {}\r
+            public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {}\r
+            public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {}\r
+            public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {}\r
+\r
+            private MidiDeviceManager owner;\r
+        }\r
+\r
+        //==============================================================================\r
+        private class MidiDeviceOpenTask extends java.util.TimerTask\r
+        {\r
+            public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device, BluetoothGatt gattToUse)\r
+            {\r
+                owner = deviceManager;\r
+                midiDevice = device;\r
+                btGatt = gattToUse;\r
+            }\r
+\r
+            @Override\r
+            public boolean cancel()\r
+            {\r
+                synchronized (MidiDeviceOpenTask.class)\r
+                {\r
+                    owner = null;\r
+                    boolean retval = super.cancel();\r
+\r
+                    if (btGatt != null)\r
+                    {\r
+                        btGatt.disconnect();\r
+                        btGatt.close();\r
+\r
+                        btGatt = null;\r
+                    }\r
+\r
+                    if (midiDevice != null)\r
+                    {\r
+                        try\r
+                        {\r
+                            midiDevice.close();\r
+                        }\r
+                        catch (IOException e)\r
+                        {}\r
+\r
+                        midiDevice = null;\r
+                    }\r
+\r
+                    return retval;\r
+                }\r
+            }\r
+\r
+            public String getBluetoothAddress()\r
+            {\r
+                synchronized (MidiDeviceOpenTask.class)\r
+                {\r
+                    if (midiDevice != null)\r
+                    {\r
+                        MidiDeviceInfo info = midiDevice.getInfo();\r
+                        if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH)\r
+                        {\r
+                            BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE);\r
+                            if (btDevice != null)\r
+                                return btDevice.getAddress();\r
+                        }\r
+                    }\r
+                }\r
+\r
+                return "";\r
+            }\r
+\r
+            public BluetoothGatt getGatt() { return btGatt; }\r
+\r
+            public int getID()\r
+            {\r
+                return midiDevice.getInfo().getId();\r
+            }\r
+\r
+            @Override\r
+            public void run()\r
+            {\r
+                synchronized (MidiDeviceOpenTask.class)\r
+                {\r
+                    if (owner != null && midiDevice != null)\r
+                        owner.onDeviceOpenedDelayed (midiDevice);\r
+                }\r
+            }\r
+\r
+            private MidiDeviceManager owner;\r
+            private MidiDevice midiDevice;\r
+            private BluetoothGatt btGatt;\r
+        }\r
+\r
+        //==============================================================================\r
+        public MidiDeviceManager()\r
+        {\r
+            manager = (MidiManager) getSystemService (MIDI_SERVICE);\r
+\r
+            if (manager == null)\r
+            {\r
+                Log.d ("JUCE", "MidiDeviceManager error: could not get MidiManager system service");\r
+                return;\r
+            }\r
+\r
+            openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> ();\r
+            midiDevices = new ArrayList<Pair<MidiDevice,BluetoothGatt>>();\r
+            openTasks = new HashMap<Integer, MidiDeviceOpenTask>();\r
+            btDevicesPairing = new HashMap<String, BluetoothGatt>();\r
+\r
+            MidiDeviceInfo[] foundDevices = manager.getDevices();\r
+            for (MidiDeviceInfo info : foundDevices)\r
+                onDeviceAdded (info);\r
+\r
+            manager.registerDeviceCallback (this, null);\r
+        }\r
+\r
+        protected void finalize() throws Throwable\r
+        {\r
+            manager.unregisterDeviceCallback (this);\r
+\r
+            synchronized (MidiDeviceManager.class)\r
+            {\r
+                btDevicesPairing.clear();\r
+\r
+                for (Integer deviceID : openTasks.keySet())\r
+                    openTasks.get (deviceID).cancel();\r
+\r
+                openTasks = null;\r
+            }\r
+\r
+            for (MidiPortPath key : openPorts.keySet())\r
+                openPorts.get (key).get().close();\r
+\r
+            openPorts = null;\r
+\r
+            for (Pair<MidiDevice, BluetoothGatt> device : midiDevices)\r
+            {\r
+                if (device.second != null)\r
+                {\r
+                    device.second.disconnect();\r
+                    device.second.close();\r
+                }\r
+\r
+                device.first.close();\r
+            }\r
+\r
+            midiDevices.clear();\r
+\r
+            super.finalize();\r
+        }\r
+\r
+        public String[] getJuceAndroidMidiInputDevices()\r
+        {\r
+            return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_OUTPUT);\r
+        }\r
+\r
+        public String[] getJuceAndroidMidiOutputDevices()\r
+        {\r
+            return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_INPUT);\r
+        }\r
+\r
+        private String[] getJuceAndroidMidiDevices (int portType)\r
+        {\r
+            // only update the list when JUCE asks for a new list\r
+            synchronized (MidiDeviceManager.class)\r
+            {\r
+                deviceInfos = getDeviceInfos();\r
+            }\r
+\r
+            ArrayList<String> portNames = new ArrayList<String>();\r
+\r
+            int index = 0;\r
+            for (MidiPortPath portInfo = getPortPathForJuceIndex (portType, index); portInfo != null; portInfo = getPortPathForJuceIndex (portType, ++index))\r
+                portNames.add (getPortName (portInfo));\r
+\r
+            String[] names = new String[portNames.size()];\r
+            return portNames.toArray (names);\r
+        }\r
+\r
+        private JuceMidiPort openMidiPortWithJuceIndex (int index, long host, boolean isInput)\r
+        {\r
+            synchronized (MidiDeviceManager.class)\r
+            {\r
+                int portTypeToFind = (isInput ? MidiDeviceInfo.PortInfo.TYPE_OUTPUT : MidiDeviceInfo.PortInfo.TYPE_INPUT);\r
+                MidiPortPath portInfo = getPortPathForJuceIndex (portTypeToFind, index);\r
+\r
+                if (portInfo != null)\r
+                {\r
+                    // ports must be opened exclusively!\r
+                    if (openPorts.containsKey (portInfo))\r
+                        return null;\r
+\r
+                    Pair<MidiDevice,BluetoothGatt> devicePair = getMidiDevicePairForId (portInfo.deviceId);\r
+\r
+                    if (devicePair != null)\r
+                    {\r
+                        MidiDevice device = devicePair.first;\r
+                        if (device != null)\r
+                        {\r
+                            JuceMidiPort juceMidiPort = null;\r
+\r
+                            if (isInput)\r
+                            {\r
+                                MidiOutputPort outputPort = device.openOutputPort(portInfo.portIndex);\r
+\r
+                                if (outputPort != null)\r
+                                    juceMidiPort = new JuceMidiInputPort(this, outputPort, portInfo, host);\r
+                            }\r
+                            else\r
+                            {\r
+                                MidiInputPort inputPort = device.openInputPort(portInfo.portIndex);\r
+\r
+                                if (inputPort != null)\r
+                                    juceMidiPort = new JuceMidiOutputPort(this, inputPort, portInfo);\r
+                            }\r
+\r
+                            if (juceMidiPort != null)\r
+                            {\r
+                                openPorts.put(portInfo, new WeakReference<JuceMidiPort>(juceMidiPort));\r
+\r
+                                return juceMidiPort;\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+\r
+            return null;\r
+        }\r
+\r
+        public JuceMidiPort openMidiInputPortWithJuceIndex (int index, long host)\r
+        {\r
+            return openMidiPortWithJuceIndex (index, host, true);\r
+        }\r
+\r
+        public JuceMidiPort openMidiOutputPortWithJuceIndex (int index)\r
+        {\r
+            return openMidiPortWithJuceIndex (index, 0, false);\r
+        }\r
+\r
+        /* 0: unpaired, 1: paired, 2: pairing */\r
+        public int getBluetoothDeviceStatus (String address)\r
+        {\r
+            synchronized (MidiDeviceManager.class)\r
+            {\r
+                if (! address.isEmpty())\r
+                {\r
+                    if (findMidiDeviceForBluetoothAddress (address) != null)\r
+                        return 1;\r
+\r
+                    if (btDevicesPairing.containsKey (address))\r
+                        return 2;\r
+\r
+                    if (findOpenTaskForBluetoothAddress (address) != null)\r
+                        return 2;\r
+                }\r
+            }\r
+\r
+            return 0;\r
+        }\r
+\r
+        public boolean pairBluetoothDevice (BluetoothDevice btDevice)\r
+        {\r
+            String btAddress = btDevice.getAddress();\r
+            if (btAddress.isEmpty())\r
+                return false;\r
+\r
+            synchronized (MidiDeviceManager.class)\r
+            {\r
+                if (getBluetoothDeviceStatus (btAddress) != 0)\r
+                    return false;\r
+\r
+\r
+                btDevicesPairing.put (btDevice.getAddress(), null);\r
+                BluetoothGatt gatt = btDevice.connectGatt (getApplicationContext(), true, new DummyBluetoothGattCallback (this));\r
+\r
+                if (gatt != null)\r
+                {\r
+                    btDevicesPairing.put (btDevice.getAddress(), gatt);\r
+                }\r
+                else\r
+                {\r
+                    pairBluetoothDeviceStepTwo (btDevice);\r
+                }\r
+            }\r
+\r
+            return true;\r
+        }\r
+\r
+        public void pairBluetoothDeviceStepTwo (BluetoothDevice btDevice)\r
+        {\r
+            manager.openBluetoothDevice(btDevice, this, null);\r
+        }\r
+\r
+        public void unpairBluetoothDevice (String address)\r
+        {\r
+            if (address.isEmpty())\r
+                return;\r
+\r
+            synchronized (MidiDeviceManager.class)\r
+            {\r
+                if (btDevicesPairing.containsKey (address))\r
+                {\r
+                    BluetoothGatt gatt = btDevicesPairing.get (address);\r
+                    if (gatt != null)\r
+                    {\r
+                        gatt.disconnect();\r
+                        gatt.close();\r
+                    }\r
+\r
+                    btDevicesPairing.remove (address);\r
+                }\r
+\r
+                MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address);\r
+                if (openTask != null)\r
+                {\r
+                    int deviceID = openTask.getID();\r
+                    openTask.cancel();\r
+                    openTasks.remove (deviceID);\r
+                }\r
+\r
+                Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (address);\r
+                if (midiDevicePair != null)\r
+                {\r
+                    MidiDevice midiDevice = midiDevicePair.first;\r
+                    onDeviceRemoved (midiDevice.getInfo());\r
+\r
+                    try {\r
+                        midiDevice.close();\r
+                    }\r
+                    catch (IOException exception)\r
+                    {\r
+                        Log.d ("JUCE", "IOException while closing midi device");\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+        private Pair<MidiDevice, BluetoothGatt> findMidiDeviceForBluetoothAddress (String address)\r
+        {\r
+            for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices)\r
+            {\r
+                MidiDeviceInfo info = midiDevice.first.getInfo();\r
+                if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH)\r
+                {\r
+                    BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE);\r
+                    if (btDevice != null && btDevice.getAddress().equals (address))\r
+                        return midiDevice;\r
+                }\r
+            }\r
+\r
+            return null;\r
+        }\r
+\r
+        private MidiDeviceOpenTask findOpenTaskForBluetoothAddress (String address)\r
+        {\r
+            for (Integer deviceID : openTasks.keySet())\r
+            {\r
+                MidiDeviceOpenTask openTask = openTasks.get (deviceID);\r
+                if (openTask.getBluetoothAddress().equals (address))\r
+                    return openTask;\r
+            }\r
+\r
+            return null;\r
+        }\r
+\r
+        public void removePort (MidiPortPath path)\r
+        {\r
+            openPorts.remove (path);\r
+        }\r
+\r
+        public String getInputPortNameForJuceIndex (int index)\r
+        {\r
+            MidiPortPath portInfo = getPortPathForJuceIndex (MidiDeviceInfo.PortInfo.TYPE_OUTPUT, index);\r
+            if (portInfo != null)\r
+                return getPortName (portInfo);\r
+\r
+            return "";\r
+        }\r
+\r
+        public String getOutputPortNameForJuceIndex (int index)\r
+        {\r
+            MidiPortPath portInfo = getPortPathForJuceIndex (MidiDeviceInfo.PortInfo.TYPE_INPUT, index);\r
+            if (portInfo != null)\r
+                return getPortName (portInfo);\r
+\r
+            return "";\r
+        }\r
+\r
+        public void onDeviceAdded (MidiDeviceInfo info)\r
+        {\r
+            // only add standard midi devices\r
+            if (info.getType() == info.TYPE_BLUETOOTH)\r
+                return;\r
+\r
+            manager.openDevice (info, this, null);\r
+        }\r
+\r
+        public void onDeviceRemoved (MidiDeviceInfo info)\r
+        {\r
+            synchronized (MidiDeviceManager.class)\r
+            {\r
+                Pair<MidiDevice, BluetoothGatt> devicePair = getMidiDevicePairForId (info.getId());\r
+\r
+                if (devicePair != null)\r
+                {\r
+                    MidiDevice midiDevice = devicePair.first;\r
+                    BluetoothGatt gatt = devicePair.second;\r
+\r
+                    // close all ports that use this device\r
+                    boolean removedPort = true;\r
+\r
+                    while (removedPort == true)\r
+                    {\r
+                        removedPort = false;\r
+                        for (MidiPortPath key : openPorts.keySet())\r
+                        {\r
+                            if (key.deviceId == info.getId())\r
+                            {\r
+                                openPorts.get(key).get().close();\r
+                                removedPort = true;\r
+                                break;\r
+                            }\r
+                        }\r
+                    }\r
+\r
+                    if (gatt != null)\r
+                    {\r
+                        gatt.disconnect();\r
+                        gatt.close();\r
+                    }\r
+\r
+                    midiDevices.remove (devicePair);\r
+                }\r
+            }\r
+        }\r
+\r
+        public void onDeviceStatusChanged (MidiDeviceStatus status)\r
+        {\r
+        }\r
+\r
+        @Override\r
+        public void onDeviceOpened (MidiDevice theDevice)\r
+        {\r
+            synchronized (MidiDeviceManager.class)\r
+            {\r
+                MidiDeviceInfo info = theDevice.getInfo();\r
+                int deviceID = info.getId();\r
+                BluetoothGatt gatt = null;\r
+                boolean isBluetooth = false;\r
+\r
+                if (! openTasks.containsKey (deviceID))\r
+                {\r
+                    if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH)\r
+                    {\r
+                        isBluetooth = true;\r
+                        BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE);\r
+                        if (btDevice != null)\r
+                        {\r
+                            String btAddress = btDevice.getAddress();\r
+                            if (btDevicesPairing.containsKey (btAddress))\r
+                            {\r
+                                gatt = btDevicesPairing.get (btAddress);\r
+                                btDevicesPairing.remove (btAddress);\r
+                            }\r
+                            else\r
+                            {\r
+                                // unpair was called in the mean time\r
+                                try\r
+                                {\r
+                                    Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress());\r
+                                    if (midiDevicePair != null)\r
+                                    {\r
+                                        gatt = midiDevicePair.second;\r
+\r
+                                        if (gatt != null)\r
+                                        {\r
+                                            gatt.disconnect();\r
+                                            gatt.close();\r
+                                        }\r
+                                    }\r
+\r
+                                    theDevice.close();\r
+                                }\r
+                                catch (IOException e)\r
+                                {}\r
+\r
+                                return;\r
+                            }\r
+                        }\r
+                    }\r
+\r
+                    MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice, gatt);\r
+                    openTasks.put (deviceID, openTask);\r
+\r
+                    new java.util.Timer().schedule (openTask, (isBluetooth ? 2000 : 100));\r
+                }\r
+            }\r
+        }\r
+\r
+        public void onDeviceOpenedDelayed (MidiDevice theDevice)\r
+        {\r
+            synchronized (MidiDeviceManager.class)\r
+            {\r
+                int deviceID = theDevice.getInfo().getId();\r
+\r
+                if (openTasks.containsKey (deviceID))\r
+                {\r
+                    if (! midiDevices.contains(theDevice))\r
+                    {\r
+                        BluetoothGatt gatt = openTasks.get (deviceID).getGatt();\r
+                        openTasks.remove (deviceID);\r
+                        midiDevices.add (new Pair<MidiDevice,BluetoothGatt> (theDevice, gatt));\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    // unpair was called in the mean time\r
+                    MidiDeviceInfo info = theDevice.getInfo();\r
+                    BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE);\r
+                    if (btDevice != null)\r
+                    {\r
+                        String btAddress = btDevice.getAddress();\r
+                        Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress());\r
+                        if (midiDevicePair != null)\r
+                        {\r
+                            BluetoothGatt gatt = midiDevicePair.second;\r
+\r
+                            if (gatt != null)\r
+                            {\r
+                                gatt.disconnect();\r
+                                gatt.close();\r
+                            }\r
+                        }\r
+                    }\r
+\r
+                    try\r
+                    {\r
+                        theDevice.close();\r
+                    }\r
+                    catch (IOException e)\r
+                    {}\r
+                }\r
+            }\r
+        }\r
+\r
+        public String getPortName(MidiPortPath path)\r
+        {\r
+            int portTypeToFind = (path.isInput ? MidiDeviceInfo.PortInfo.TYPE_INPUT : MidiDeviceInfo.PortInfo.TYPE_OUTPUT);\r
+\r
+            synchronized (MidiDeviceManager.class)\r
+            {\r
+                for (MidiDeviceInfo info : deviceInfos)\r
+                {\r
+                    int localIndex = 0;\r
+                    if (info.getId() == path.deviceId)\r
+                    {\r
+                        for (MidiDeviceInfo.PortInfo portInfo : info.getPorts())\r
+                        {\r
+                            int portType = portInfo.getType();\r
+                            if (portType == portTypeToFind)\r
+                            {\r
+                                int portIndex = portInfo.getPortNumber();\r
+                                if (portIndex == path.portIndex)\r
+                                {\r
+                                    String portName = portInfo.getName();\r
+                                    if (portName.isEmpty())\r
+                                        portName = (String) info.getProperties().get(info.PROPERTY_NAME);\r
+\r
+                                    return portName;\r
+                                }\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+\r
+            return "";\r
+        }\r
+\r
+        public MidiPortPath getPortPathForJuceIndex (int portType, int juceIndex)\r
+        {\r
+            int portIdx = 0;\r
+            for (MidiDeviceInfo info : deviceInfos)\r
+            {\r
+                for (MidiDeviceInfo.PortInfo portInfo : info.getPorts())\r
+                {\r
+                    if (portInfo.getType() == portType)\r
+                    {\r
+                        if (portIdx == juceIndex)\r
+                            return new MidiPortPath (info.getId(),\r
+                                    (portType == MidiDeviceInfo.PortInfo.TYPE_INPUT),\r
+                                    portInfo.getPortNumber());\r
+\r
+                        portIdx++;\r
+                    }\r
+                }\r
+            }\r
+\r
+            return null;\r
+        }\r
+\r
+        private MidiDeviceInfo[] getDeviceInfos()\r
+        {\r
+            synchronized (MidiDeviceManager.class)\r
+            {\r
+                MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size()];\r
+\r
+                int idx = 0;\r
+                for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices)\r
+                    infos[idx++] = midiDevice.first.getInfo();\r
+\r
+                return infos;\r
+            }\r
+        }\r
+\r
+        private Pair<MidiDevice, BluetoothGatt> getMidiDevicePairForId (int deviceId)\r
+        {\r
+            synchronized (MidiDeviceManager.class)\r
+            {\r
+                for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices)\r
+                    if (midiDevice.first.getInfo().getId() == deviceId)\r
+                        return midiDevice;\r
+            }\r
+\r
+            return null;\r
+        }\r
+\r
+        private MidiManager manager;\r
+        private HashMap<String, BluetoothGatt> btDevicesPairing;\r
+        private HashMap<Integer, MidiDeviceOpenTask> openTasks;\r
+        private ArrayList<Pair<MidiDevice, BluetoothGatt>> midiDevices;\r
+        private MidiDeviceInfo[] deviceInfos;\r
+        private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts;\r
+    }\r
+\r
+    public MidiDeviceManager getAndroidMidiDeviceManager()\r
+    {\r
+        if (getSystemService (MIDI_SERVICE) == null)\r
+            return null;\r
+\r
+        synchronized (AudioPluginHost.class)\r
+        {\r
+            if (midiDeviceManager == null)\r
+                midiDeviceManager = new MidiDeviceManager();\r
+        }\r
+\r
+        return midiDeviceManager;\r
+    }\r
+\r
+    public BluetoothManager getAndroidBluetoothManager()\r
+    {\r
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();\r
+\r
+        if (adapter == null)\r
+            return null;\r
+\r
+        if (adapter.getBluetoothLeScanner() == null)\r
+            return null;\r
+\r
+        synchronized (AudioPluginHost.class)\r
+        {\r
+            if (bluetoothManager == null)\r
+                bluetoothManager = new BluetoothManager();\r
+        }\r
+\r
+        return bluetoothManager;\r
+    }\r
+\r
+    //==============================================================================\r
+    @Override\r
+    public void onCreate (Bundle savedInstanceState)\r
+    {\r
+        super.onCreate (savedInstanceState);\r
+\r
+        isScreenSaverEnabled = true;\r
+        hideActionBar();\r
+        viewHolder = new ViewHolder (this);\r
+        setContentView (viewHolder);\r
+\r
+        setVolumeControlStream (AudioManager.STREAM_MUSIC);\r
+\r
+        permissionCallbackPtrMap = new HashMap<Integer, Long>();\r
+    }\r
+\r
+    @Override\r
+    protected void onDestroy()\r
+    {\r
+        quitApp();\r
+        super.onDestroy();\r
+\r
+        clearDataCache();\r
+    }\r
+\r
+    @Override\r
+    protected void onPause()\r
+    {\r
+        suspendApp();\r
+\r
+        try\r
+        {\r
+            Thread.sleep (1000); // This is a bit of a hack to avoid some hard-to-track-down\r
+                                 // openGL glitches when pausing/resuming apps..\r
+        } catch (InterruptedException e) {}\r
+\r
+        super.onPause();\r
+    }\r
+\r
+    @Override\r
+    protected void onResume()\r
+    {\r
+        super.onResume();\r
+        resumeApp();\r
+\r
+        // Ensure that navigation/status bar visibility is correctly restored.\r
+        for (int i = 0; i < viewHolder.getChildCount(); ++i)\r
+        {\r
+            if (viewHolder.getChildAt (i) instanceof ComponentPeerView)\r
+                ((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void onConfigurationChanged (Configuration cfg)\r
+    {\r
+        super.onConfigurationChanged (cfg);\r
+        setContentView (viewHolder);\r
+    }\r
+\r
+    private void callAppLauncher()\r
+    {\r
+        launchApp (getApplicationInfo().publicSourceDir,\r
+                   getApplicationInfo().dataDir);\r
+    }\r
+\r
+    // Need to override this as the default implementation always finishes the activity.\r
+    @Override\r
+    public void onBackPressed()\r
+    {\r
+        ComponentPeerView focusedView = getViewWithFocusOrDefaultView();\r
+\r
+        if (focusedView == null)\r
+            return;\r
+\r
+        focusedView.backButtonPressed();\r
+    }\r
+\r
+    private ComponentPeerView getViewWithFocusOrDefaultView()\r
+    {\r
+        for (int i = 0; i < viewHolder.getChildCount(); ++i)\r
+        {\r
+            if (viewHolder.getChildAt (i).hasFocus())\r
+                return (ComponentPeerView) viewHolder.getChildAt (i);\r
+        }\r
+\r
+        if (viewHolder.getChildCount() > 0)\r
+            return (ComponentPeerView) viewHolder.getChildAt (0);\r
+\r
+        return null;\r
+    }\r
+\r
+    //==============================================================================\r
+    private void hideActionBar()\r
+    {\r
+        // get "getActionBar" method\r
+        java.lang.reflect.Method getActionBarMethod = null;\r
+        try\r
+        {\r
+            getActionBarMethod = this.getClass().getMethod ("getActionBar");\r
+        }\r
+        catch (SecurityException e)     { return; }\r
+        catch (NoSuchMethodException e) { return; }\r
+        if (getActionBarMethod == null) return;\r
+\r
+        // invoke "getActionBar" method\r
+        Object actionBar = null;\r
+        try\r
+        {\r
+            actionBar = getActionBarMethod.invoke (this);\r
+        }\r
+        catch (java.lang.IllegalArgumentException e) { return; }\r
+        catch (java.lang.IllegalAccessException e) { return; }\r
+        catch (java.lang.reflect.InvocationTargetException e) { return; }\r
+        if (actionBar == null) return;\r
+\r
+        // get "hide" method\r
+        java.lang.reflect.Method actionBarHideMethod = null;\r
+        try\r
+        {\r
+            actionBarHideMethod = actionBar.getClass().getMethod ("hide");\r
+        }\r
+        catch (SecurityException e)     { return; }\r
+        catch (NoSuchMethodException e) { return; }\r
+        if (actionBarHideMethod == null) return;\r
+\r
+        // invoke "hide" method\r
+        try\r
+        {\r
+            actionBarHideMethod.invoke (actionBar);\r
+        }\r
+        catch (java.lang.IllegalArgumentException e) {}\r
+        catch (java.lang.IllegalAccessException e) {}\r
+        catch (java.lang.reflect.InvocationTargetException e) {}\r
+    }\r
+\r
+    void requestPermissionsCompat (String[] permissions, int requestCode)\r
+    {\r
+        Method requestPermissionsMethod = null;\r
+        try\r
+        {\r
+            requestPermissionsMethod = this.getClass().getMethod ("requestPermissions",\r
+                                                                  String[].class, int.class);\r
+        }\r
+        catch (SecurityException e)     { return; }\r
+        catch (NoSuchMethodException e) { return; }\r
+        if (requestPermissionsMethod == null) return;\r
+\r
+        try\r
+        {\r
+            requestPermissionsMethod.invoke (this, permissions, requestCode);\r
+        }\r
+        catch (java.lang.IllegalArgumentException e) {}\r
+        catch (java.lang.IllegalAccessException e) {}\r
+        catch (java.lang.reflect.InvocationTargetException e) {}\r
+    }\r
+\r
+    //==============================================================================\r
+    private native void launchApp (String appFile, String appDataDir);\r
+    private native void quitApp();\r
+    private native void suspendApp();\r
+    private native void resumeApp();\r
+    private native void setScreenSize (int screenWidth, int screenHeight, int dpi);\r
+    private native void appActivityResult (int requestCode, int resultCode, Intent data);\r
+    private native void appNewIntent (Intent intent);\r
+\r
+    //==============================================================================\r
+    private ViewHolder viewHolder;\r
+    private MidiDeviceManager midiDeviceManager = null;\r
+    private BluetoothManager bluetoothManager = null;\r
+    private boolean isScreenSaverEnabled;\r
+    private java.util.Timer keepAliveTimer;\r
+\r
+    public final ComponentPeerView createNewView (boolean opaque, long host)\r
+    {\r
+        ComponentPeerView v = new ComponentPeerView (this, opaque, host);\r
+        viewHolder.addView (v);\r
+        return v;\r
+    }\r
+\r
+    public final void deleteView (ComponentPeerView view)\r
+    {\r
+        view.host = 0;\r
+\r
+        ViewGroup group = (ViewGroup) (view.getParent());\r
+\r
+        if (group != null)\r
+            group.removeView (view);\r
+    }\r
+\r
+    public final void deleteNativeSurfaceView (NativeSurfaceView view)\r
+    {\r
+        ViewGroup group = (ViewGroup) (view.getParent());\r
+\r
+        if (group != null)\r
+            group.removeView (view);\r
+    }\r
+\r
+    final class ViewHolder  extends ViewGroup\r
+    {\r
+        public ViewHolder (Context context)\r
+        {\r
+            super (context);\r
+            setDescendantFocusability (ViewGroup.FOCUS_AFTER_DESCENDANTS);\r
+            setFocusable (false);\r
+        }\r
+\r
+        protected final void onLayout (boolean changed, int left, int top, int right, int bottom)\r
+        {\r
+            setScreenSize (getWidth(), getHeight(), getDPI());\r
+\r
+            if (isFirstResize)\r
+            {\r
+                isFirstResize = false;\r
+                callAppLauncher();\r
+            }\r
+        }\r
+\r
+        private final int getDPI()\r
+        {\r
+            DisplayMetrics metrics = new DisplayMetrics();\r
+            getWindowManager().getDefaultDisplay().getMetrics (metrics);\r
+            return metrics.densityDpi;\r
+        }\r
+\r
+        private boolean isFirstResize = true;\r
+    }\r
+\r
+    public final void excludeClipRegion (android.graphics.Canvas canvas, float left, float top, float right, float bottom)\r
+    {\r
+        canvas.clipRect (left, top, right, bottom, android.graphics.Region.Op.DIFFERENCE);\r
+    }\r
+\r
+    //==============================================================================\r
+    public final void setScreenSaver (boolean enabled)\r
+    {\r
+        if (isScreenSaverEnabled != enabled)\r
+        {\r
+            isScreenSaverEnabled = enabled;\r
+\r
+            if (keepAliveTimer != null)\r
+            {\r
+                keepAliveTimer.cancel();\r
+                keepAliveTimer = null;\r
+            }\r
+\r
+            if (enabled)\r
+            {\r
+                getWindow().clearFlags (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\r
+            }\r
+            else\r
+            {\r
+                getWindow().addFlags (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\r
+\r
+                // If no user input is received after about 3 seconds, the OS will lower the\r
+                // task's priority, so this timer forces it to be kept active.\r
+                keepAliveTimer = new java.util.Timer();\r
+\r
+                keepAliveTimer.scheduleAtFixedRate (new TimerTask()\r
+                {\r
+                    @Override\r
+                    public void run()\r
+                    {\r
+                        android.app.Instrumentation instrumentation = new android.app.Instrumentation();\r
+\r
+                        try\r
+                        {\r
+                            instrumentation.sendKeyDownUpSync (KeyEvent.KEYCODE_UNKNOWN);\r
+                        }\r
+                        catch (Exception e)\r
+                        {\r
+                        }\r
+                    }\r
+                }, 2000, 2000);\r
+            }\r
+        }\r
+    }\r
+\r
+    public final boolean getScreenSaver()\r
+    {\r
+        return isScreenSaverEnabled;\r
+    }\r
+\r
+    //==============================================================================\r
+    public final String getClipboardContent()\r
+    {\r
+        ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE);\r
+        return clipboard.getText().toString();\r
+    }\r
+\r
+    public final void setClipboardContent (String newText)\r
+    {\r
+        ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE);\r
+        clipboard.setText (newText);\r
+    }\r
+\r
+    //==============================================================================\r
+    public final void showMessageBox (String title, String message, final long callback)\r
+    {\r
+        AlertDialog.Builder builder = new AlertDialog.Builder (this);\r
+        builder.setTitle (title)\r
+               .setMessage (message)\r
+               .setCancelable (true)\r
+               .setOnCancelListener (new DialogInterface.OnCancelListener()\r
+                    {\r
+                        public void onCancel (DialogInterface dialog)\r
+                        {\r
+                            AudioPluginHost.this.alertDismissed (callback, 0);\r
+                        }\r
+                    })\r
+               .setPositiveButton ("OK", new DialogInterface.OnClickListener()\r
+                    {\r
+                        public void onClick (DialogInterface dialog, int id)\r
+                        {\r
+                            dialog.dismiss();\r
+                            AudioPluginHost.this.alertDismissed (callback, 0);\r
+                        }\r
+                    });\r
+\r
+        builder.create().show();\r
+    }\r
+\r
+    public final void showOkCancelBox (String title, String message, final long callback,\r
+                                       String okButtonText, String cancelButtonText)\r
+    {\r
+        AlertDialog.Builder builder = new AlertDialog.Builder (this);\r
+        builder.setTitle (title)\r
+               .setMessage (message)\r
+               .setCancelable (true)\r
+               .setOnCancelListener (new DialogInterface.OnCancelListener()\r
+                    {\r
+                        public void onCancel (DialogInterface dialog)\r
+                        {\r
+                            AudioPluginHost.this.alertDismissed (callback, 0);\r
+                        }\r
+                    })\r
+               .setPositiveButton (okButtonText.isEmpty() ? "OK" : okButtonText, new DialogInterface.OnClickListener()\r
+                    {\r
+                        public void onClick (DialogInterface dialog, int id)\r
+                        {\r
+                            dialog.dismiss();\r
+                            AudioPluginHost.this.alertDismissed (callback, 1);\r
+                        }\r
+                    })\r
+               .setNegativeButton (cancelButtonText.isEmpty() ? "Cancel" : cancelButtonText, new DialogInterface.OnClickListener()\r
+                    {\r
+                        public void onClick (DialogInterface dialog, int id)\r
+                        {\r
+                            dialog.dismiss();\r
+                            AudioPluginHost.this.alertDismissed (callback, 0);\r
+                        }\r
+                    });\r
+\r
+        builder.create().show();\r
+    }\r
+\r
+    public final void showYesNoCancelBox (String title, String message, final long callback)\r
+    {\r
+        AlertDialog.Builder builder = new AlertDialog.Builder (this);\r
+        builder.setTitle (title)\r
+               .setMessage (message)\r
+               .setCancelable (true)\r
+               .setOnCancelListener (new DialogInterface.OnCancelListener()\r
+                    {\r
+                        public void onCancel (DialogInterface dialog)\r
+                        {\r
+                            AudioPluginHost.this.alertDismissed (callback, 0);\r
+                        }\r
+                    })\r
+               .setPositiveButton ("Yes", new DialogInterface.OnClickListener()\r
+                    {\r
+                        public void onClick (DialogInterface dialog, int id)\r
+                        {\r
+                            dialog.dismiss();\r
+                            AudioPluginHost.this.alertDismissed (callback, 1);\r
+                        }\r
+                    })\r
+               .setNegativeButton ("No", new DialogInterface.OnClickListener()\r
+                    {\r
+                        public void onClick (DialogInterface dialog, int id)\r
+                        {\r
+                            dialog.dismiss();\r
+                            AudioPluginHost.this.alertDismissed (callback, 2);\r
+                        }\r
+                    })\r
+               .setNeutralButton ("Cancel", new DialogInterface.OnClickListener()\r
+                    {\r
+                        public void onClick (DialogInterface dialog, int id)\r
+                        {\r
+                            dialog.dismiss();\r
+                            AudioPluginHost.this.alertDismissed (callback, 0);\r
+                        }\r
+                    });\r
+\r
+        builder.create().show();\r
+    }\r
+\r
+    public native void alertDismissed (long callback, int id);\r
+\r
+    //==============================================================================\r
+    public final class ComponentPeerView extends ViewGroup\r
+                                         implements View.OnFocusChangeListener\r
+    {\r
+        public ComponentPeerView (Context context, boolean opaque_, long host)\r
+        {\r
+            super (context);\r
+            this.host = host;\r
+            setWillNotDraw (false);\r
+            opaque = opaque_;\r
+\r
+            setFocusable (true);\r
+            setFocusableInTouchMode (true);\r
+            setOnFocusChangeListener (this);\r
+\r
+            // swap red and blue colours to match internal opengl texture format\r
+            ColorMatrix colorMatrix = new ColorMatrix();\r
+\r
+            float[] colorTransform = { 0,    0,    1.0f, 0,    0,\r
+                                       0,    1.0f, 0,    0,    0,\r
+                                       1.0f, 0,    0,    0,    0,\r
+                                       0,    0,    0,    1.0f, 0 };\r
+\r
+            colorMatrix.set (colorTransform);\r
+            paint.setColorFilter (new ColorMatrixColorFilter (colorMatrix));\r
+\r
+            java.lang.reflect.Method method = null;\r
+\r
+            try\r
+            {\r
+                method = getClass().getMethod ("setLayerType", int.class, Paint.class);\r
+            }\r
+            catch (SecurityException e)     {}\r
+            catch (NoSuchMethodException e) {}\r
+\r
+            if (method != null)\r
+            {\r
+                try\r
+                {\r
+                    int layerTypeNone = 0;\r
+                    method.invoke (this, layerTypeNone, null);\r
+                }\r
+                catch (java.lang.IllegalArgumentException e) {}\r
+                catch (java.lang.IllegalAccessException e) {}\r
+                catch (java.lang.reflect.InvocationTargetException e) {}\r
+            }\r
+        }\r
+\r
+        //==============================================================================\r
+        private native void handlePaint (long host, Canvas canvas, Paint paint);\r
+\r
+        @Override\r
+        public void onDraw (Canvas canvas)\r
+        {\r
+            if (host == 0)\r
+                return;\r
+\r
+            handlePaint (host, canvas, paint);\r
+        }\r
+\r
+        @Override\r
+        public boolean isOpaque()\r
+        {\r
+            return opaque;\r
+        }\r
+\r
+        private boolean opaque;\r
+        private long host;\r
+        private Paint paint = new Paint();\r
+\r
+        //==============================================================================\r
+        private native void handleMouseDown (long host, int index, float x, float y, long time);\r
+        private native void handleMouseDrag (long host, int index, float x, float y, long time);\r
+        private native void handleMouseUp   (long host, int index, float x, float y, long time);\r
+\r
+        @Override\r
+        public boolean onTouchEvent (MotionEvent event)\r
+        {\r
+            if (host == 0)\r
+                return false;\r
+\r
+            int action = event.getAction();\r
+            long time = event.getEventTime();\r
+\r
+            switch (action & MotionEvent.ACTION_MASK)\r
+            {\r
+                case MotionEvent.ACTION_DOWN:\r
+                    handleMouseDown (host, event.getPointerId(0), event.getX(), event.getY(), time);\r
+                    return true;\r
+\r
+                case MotionEvent.ACTION_CANCEL:\r
+                case MotionEvent.ACTION_UP:\r
+                    handleMouseUp (host, event.getPointerId(0), event.getX(), event.getY(), time);\r
+                    return true;\r
+\r
+                case MotionEvent.ACTION_MOVE:\r
+                {\r
+                    int n = event.getPointerCount();\r
+                    for (int i = 0; i < n; ++i)\r
+                        handleMouseDrag (host, event.getPointerId(i), event.getX(i), event.getY(i), time);\r
+\r
+                    return true;\r
+                }\r
+\r
+                case MotionEvent.ACTION_POINTER_UP:\r
+                {\r
+                    int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;\r
+                    handleMouseUp (host, event.getPointerId(i), event.getX(i), event.getY(i), time);\r
+                    return true;\r
+                }\r
+\r
+                case MotionEvent.ACTION_POINTER_DOWN:\r
+                {\r
+                    int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;\r
+                    handleMouseDown (host, event.getPointerId(i), event.getX(i), event.getY(i), time);\r
+                    return true;\r
+                }\r
+\r
+                default:\r
+                    break;\r
+            }\r
+\r
+            return false;\r
+        }\r
+\r
+        //==============================================================================\r
+        private native void handleKeyDown (long host, int keycode, int textchar);\r
+        private native void handleKeyUp (long host, int keycode, int textchar);\r
+        private native void handleBackButton (long host);\r
+        private native void handleKeyboardHidden (long host);\r
+\r
+        public void showKeyboard (String type)\r
+        {\r
+            InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE);\r
+\r
+            if (imm != null)\r
+            {\r
+                if (type.length() > 0)\r
+                {\r
+                    imm.showSoftInput (this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT);\r
+                    imm.setInputMethod (getWindowToken(), type);\r
+                    keyboardDismissListener.startListening();\r
+                }\r
+                else\r
+                {\r
+                    imm.hideSoftInputFromWindow (getWindowToken(), 0);\r
+                    keyboardDismissListener.stopListening();\r
+                }\r
+            }\r
+        }\r
+\r
+        public void backButtonPressed()\r
+        {\r
+            if (host == 0)\r
+                return;\r
+\r
+            handleBackButton (host);\r
+        }\r
+\r
+        @Override\r
+        public boolean onKeyDown (int keyCode, KeyEvent event)\r
+        {\r
+            if (host == 0)\r
+                return false;\r
+\r
+            switch (keyCode)\r
+            {\r
+                case KeyEvent.KEYCODE_VOLUME_UP:\r
+                case KeyEvent.KEYCODE_VOLUME_DOWN:\r
+                    return super.onKeyDown (keyCode, event);\r
+                case KeyEvent.KEYCODE_BACK:\r
+                {\r
+                    ((Activity) getContext()).onBackPressed();\r
+                    return true;\r
+                }\r
+\r
+                default:\r
+                    break;\r
+            }\r
+\r
+            handleKeyDown (host, keyCode, event.getUnicodeChar());\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public boolean onKeyUp (int keyCode, KeyEvent event)\r
+        {\r
+            if (host == 0)\r
+                return false;\r
+\r
+            handleKeyUp (host, keyCode, event.getUnicodeChar());\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public boolean onKeyMultiple (int keyCode, int count, KeyEvent event)\r
+        {\r
+            if (host == 0)\r
+                return false;\r
+\r
+            if (keyCode != KeyEvent.KEYCODE_UNKNOWN || event.getAction() != KeyEvent.ACTION_MULTIPLE)\r
+                return super.onKeyMultiple (keyCode, count, event);\r
+\r
+            if (event.getCharacters() != null)\r
+            {\r
+                int utf8Char = event.getCharacters().codePointAt (0);\r
+                handleKeyDown (host, utf8Char, utf8Char);\r
+                return true;\r
+            }\r
+\r
+            return false;\r
+        }\r
+\r
+        //==============================================================================\r
+        private final class KeyboardDismissListener\r
+        {\r
+            public KeyboardDismissListener (ComponentPeerView viewToUse)\r
+            {\r
+                view = viewToUse;\r
+            }\r
+\r
+            private void startListening()\r
+            {\r
+                view.getViewTreeObserver().addOnGlobalLayoutListener(viewTreeObserver);\r
+            }\r
+\r
+            private void stopListening()\r
+            {\r
+                view.getViewTreeObserver().removeGlobalOnLayoutListener(viewTreeObserver);\r
+            }\r
+\r
+            private class TreeObserver implements ViewTreeObserver.OnGlobalLayoutListener\r
+            {\r
+                TreeObserver()\r
+                {\r
+                    keyboardShown = false;\r
+                }\r
+\r
+                @Override\r
+                public void onGlobalLayout()\r
+                {\r
+                    Rect r = new Rect();\r
+\r
+                    ViewGroup parentView = (ViewGroup) getParent();\r
+\r
+                    if (parentView == null)\r
+                        return;\r
+\r
+                    parentView.getWindowVisibleDisplayFrame (r);\r
+\r
+                    int diff = parentView.getHeight() - (r.bottom - r.top);\r
+\r
+                    // Arbitrary threshold, surely keyboard would take more than 20 pix.\r
+                    if (diff < 20 && keyboardShown)\r
+                    {\r
+                        keyboardShown = false;\r
+                        handleKeyboardHidden (view.host);\r
+                    }\r
+\r
+                    if (! keyboardShown && diff > 20)\r
+                        keyboardShown = true;\r
+                };\r
+\r
+                private boolean keyboardShown;\r
+            };\r
+\r
+            private ComponentPeerView view;\r
+            private TreeObserver viewTreeObserver = new TreeObserver();\r
+        }\r
+\r
+        private KeyboardDismissListener keyboardDismissListener = new KeyboardDismissListener(this);\r
+\r
+        // this is here to make keyboard entry work on a Galaxy Tab2 10.1\r
+        @Override\r
+        public InputConnection onCreateInputConnection (EditorInfo outAttrs)\r
+        {\r
+            outAttrs.actionLabel = "";\r
+            outAttrs.hintText = "";\r
+            outAttrs.initialCapsMode = 0;\r
+            outAttrs.initialSelEnd = outAttrs.initialSelStart = -1;\r
+            outAttrs.label = "";\r
+            outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI;\r
+            outAttrs.inputType = InputType.TYPE_NULL;\r
+\r
+            return new BaseInputConnection (this, false);\r
+        }\r
+\r
+        //==============================================================================\r
+        @Override\r
+        protected void onSizeChanged (int w, int h, int oldw, int oldh)\r
+        {\r
+            if (host == 0)\r
+                return;\r
+\r
+            super.onSizeChanged (w, h, oldw, oldh);\r
+            viewSizeChanged (host);\r
+        }\r
+\r
+        @Override\r
+        protected void onLayout (boolean changed, int left, int top, int right, int bottom)\r
+        {\r
+            for (int i = getChildCount(); --i >= 0;)\r
+                requestTransparentRegion (getChildAt (i));\r
+        }\r
+\r
+        private native void viewSizeChanged (long host);\r
+\r
+        @Override\r
+        public void onFocusChange (View v, boolean hasFocus)\r
+        {\r
+            if (host == 0)\r
+                return;\r
+\r
+            if (v == this)\r
+                focusChanged (host, hasFocus);\r
+        }\r
+\r
+        private native void focusChanged (long host, boolean hasFocus);\r
+\r
+        public void setViewName (String newName)    {}\r
+\r
+        public void setSystemUiVisibilityCompat (int visibility)\r
+        {\r
+            Method systemUIVisibilityMethod = null;\r
+            try\r
+            {\r
+                systemUIVisibilityMethod = this.getClass().getMethod ("setSystemUiVisibility", int.class);\r
+            }\r
+            catch (SecurityException e)     { return; }\r
+            catch (NoSuchMethodException e) { return; }\r
+            if (systemUIVisibilityMethod == null) return;\r
+\r
+            try\r
+            {\r
+                systemUIVisibilityMethod.invoke (this, visibility);\r
+            }\r
+            catch (java.lang.IllegalArgumentException e) {}\r
+            catch (java.lang.IllegalAccessException e) {}\r
+            catch (java.lang.reflect.InvocationTargetException e) {}\r
+        }\r
+\r
+        public boolean isVisible()                  { return getVisibility() == VISIBLE; }\r
+        public void setVisible (boolean b)          { setVisibility (b ? VISIBLE : INVISIBLE); }\r
+\r
+        public boolean containsPoint (int x, int y)\r
+        {\r
+            return true; //xxx needs to check overlapping views\r
+        }\r
+\r
+        //==============================================================================\r
+        private native void handleAppResumed (long host);\r
+\r
+        public void appResumed()\r
+        {\r
+            if (host == 0)\r
+                return;\r
+\r
+            handleAppResumed (host);\r
+        }\r
+    }\r
+\r
+    //==============================================================================\r
+    public static class NativeSurfaceView    extends SurfaceView\r
+                                          implements SurfaceHolder.Callback\r
+    {\r
+        private long nativeContext = 0;\r
+\r
+        NativeSurfaceView (Context context, long nativeContextPtr)\r
+        {\r
+            super (context);\r
+            nativeContext = nativeContextPtr;\r
+        }\r
+\r
+        public Surface getNativeSurface()\r
+        {\r
+            Surface retval = null;\r
+\r
+            SurfaceHolder holder = getHolder();\r
+            if (holder != null)\r
+                retval = holder.getSurface();\r
+\r
+            return retval;\r
+        }\r
+\r
+        //==============================================================================\r
+        @Override\r
+        public void surfaceChanged (SurfaceHolder holder, int format, int width, int height)\r
+        {\r
+            surfaceChangedNative (nativeContext, holder, format, width, height);\r
+        }\r
+\r
+        @Override\r
+        public void surfaceCreated (SurfaceHolder holder)\r
+        {\r
+            surfaceCreatedNative (nativeContext, holder);\r
+        }\r
+\r
+        @Override\r
+        public void surfaceDestroyed (SurfaceHolder holder)\r
+        {\r
+            surfaceDestroyedNative (nativeContext, holder);\r
+        }\r
+\r
+        @Override\r
+        protected void dispatchDraw (Canvas canvas)\r
+        {\r
+            super.dispatchDraw (canvas);\r
+            dispatchDrawNative (nativeContext, canvas);\r
+        }\r
+\r
+        //==============================================================================\r
+        @Override\r
+        protected void onAttachedToWindow ()\r
+        {\r
+            super.onAttachedToWindow();\r
+            getHolder().addCallback (this);\r
+        }\r
+\r
+        @Override\r
+        protected void onDetachedFromWindow ()\r
+        {\r
+            super.onDetachedFromWindow();\r
+            getHolder().removeCallback (this);\r
+        }\r
+\r
+        //==============================================================================\r
+        private native void dispatchDrawNative (long nativeContextPtr, Canvas canvas);\r
+        private native void surfaceCreatedNative (long nativeContextptr, SurfaceHolder holder);\r
+        private native void surfaceDestroyedNative (long nativeContextptr, SurfaceHolder holder);\r
+        private native void surfaceChangedNative (long nativeContextptr, SurfaceHolder holder,\r
+                                                  int format, int width, int height);\r
+    }\r
+\r
+    public NativeSurfaceView createNativeSurfaceView (long nativeSurfacePtr)\r
+    {\r
+        return new NativeSurfaceView (this, nativeSurfacePtr);\r
+    }\r
+\r
+    //==============================================================================\r
+    public final int[] renderGlyph (char glyph1, char glyph2, Paint paint, android.graphics.Matrix matrix, Rect bounds)\r
+    {\r
+        Path p = new Path();\r
+\r
+        char[] str = { glyph1, glyph2 };\r
+        paint.getTextPath (str, 0, (glyph2 != 0 ? 2 : 1), 0.0f, 0.0f, p);\r
+\r
+        RectF boundsF = new RectF();\r
+        p.computeBounds (boundsF, true);\r
+        matrix.mapRect (boundsF);\r
+\r
+        boundsF.roundOut (bounds);\r
+        bounds.left--;\r
+        bounds.right++;\r
+\r
+        final int w = bounds.width();\r
+        final int h = Math.max (1, bounds.height());\r
+\r
+        Bitmap bm = Bitmap.createBitmap (w, h, Bitmap.Config.ARGB_8888);\r
+\r
+        Canvas c = new Canvas (bm);\r
+        matrix.postTranslate (-bounds.left, -bounds.top);\r
+        c.setMatrix (matrix);\r
+        c.drawPath (p, paint);\r
+\r
+        final int sizeNeeded = w * h;\r
+        if (cachedRenderArray.length < sizeNeeded)\r
+            cachedRenderArray = new int [sizeNeeded];\r
+\r
+        bm.getPixels (cachedRenderArray, 0, w, 0, 0, w, h);\r
+        bm.recycle();\r
+        return cachedRenderArray;\r
+    }\r
+\r
+    private int[] cachedRenderArray = new int [256];\r
+\r
+    //==============================================================================\r
+    public static class NativeInvocationHandler implements InvocationHandler\r
+    {\r
+        public NativeInvocationHandler (Activity activityToUse, long nativeContextRef)\r
+        {\r
+            activity = activityToUse;\r
+            nativeContext = nativeContextRef;\r
+        }\r
+\r
+        public void nativeContextDeleted()\r
+        {\r
+            nativeContext = 0;\r
+        }\r
+\r
+        @Override\r
+        public void finalize()\r
+        {\r
+            activity.runOnUiThread (new Runnable()\r
+                                    {\r
+                                        @Override\r
+                                        public void run()\r
+                                        {\r
+                                            if (nativeContext != 0)\r
+                                                dispatchFinalize (nativeContext);\r
+                                        }\r
+                                    });\r
+        }\r
+\r
+        @Override\r
+        public Object invoke (Object proxy, Method method, Object[] args) throws Throwable\r
+        {\r
+            return dispatchInvoke (nativeContext, proxy, method, args);\r
+        }\r
+\r
+        //==============================================================================\r
+        Activity activity;\r
+        private long nativeContext = 0;\r
+\r
+        private native void dispatchFinalize (long nativeContextRef);\r
+        private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args);\r
+    }\r
+\r
+    public InvocationHandler createInvocationHandler (long nativeContextRef)\r
+    {\r
+        return new NativeInvocationHandler (this, nativeContextRef);\r
+    }\r
+\r
+    public void invocationHandlerContextDeleted (InvocationHandler handler)\r
+    {\r
+        ((NativeInvocationHandler) handler).nativeContextDeleted();\r
+    }\r
+\r
+    //==============================================================================\r
+    public static class HTTPStream\r
+    {\r
+        public HTTPStream (String address, boolean isPostToUse, byte[] postDataToUse,\r
+                           String headersToUse, int timeOutMsToUse,\r
+                           int[] statusCodeToUse, StringBuffer responseHeadersToUse,\r
+                           int numRedirectsToFollowToUse, String httpRequestCmdToUse) throws IOException\r
+        {\r
+            isPost = isPostToUse;\r
+            postData = postDataToUse;\r
+            headers = headersToUse;\r
+            timeOutMs = timeOutMsToUse;\r
+            statusCode = statusCodeToUse;\r
+            responseHeaders = responseHeadersToUse;\r
+            totalLength = -1;\r
+            numRedirectsToFollow = numRedirectsToFollowToUse;\r
+            httpRequestCmd = httpRequestCmdToUse;\r
+\r
+            connection = createConnection (address, isPost, postData, headers, timeOutMs, httpRequestCmd);\r
+        }\r
+\r
+        private final HttpURLConnection createConnection (String address, boolean isPost, byte[] postData,\r
+                                                          String headers, int timeOutMs, String httpRequestCmdToUse) throws IOException\r
+        {\r
+            HttpURLConnection newConnection = (HttpURLConnection) (new URL(address).openConnection());\r
+\r
+            try\r
+            {\r
+                newConnection.setInstanceFollowRedirects (false);\r
+                newConnection.setConnectTimeout (timeOutMs);\r
+                newConnection.setReadTimeout (timeOutMs);\r
+\r
+                // 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.\r
+                // So convert headers string to an array, with an element for each line\r
+                String headerLines[] = headers.split("\\n");\r
+\r
+                // Set request headers\r
+                for (int i = 0; i < headerLines.length; ++i)\r
+                {\r
+                    int pos = headerLines[i].indexOf (":");\r
+\r
+                    if (pos > 0 && pos < headerLines[i].length())\r
+                    {\r
+                        String field = headerLines[i].substring (0, pos);\r
+                        String value = headerLines[i].substring (pos + 1);\r
+\r
+                        if (value.length() > 0)\r
+                            newConnection.setRequestProperty (field, value);\r
+                    }\r
+                }\r
+\r
+                newConnection.setRequestMethod (httpRequestCmd);\r
+\r
+                if (isPost)\r
+                {\r
+                    newConnection.setDoOutput (true);\r
+\r
+                    if (postData != null)\r
+                    {\r
+                        OutputStream out = newConnection.getOutputStream();\r
+                        out.write(postData);\r
+                        out.flush();\r
+                    }\r
+                }\r
+\r
+                return newConnection;\r
+            }\r
+            catch (Throwable e)\r
+            {\r
+                newConnection.disconnect();\r
+                throw new IOException ("Connection error");\r
+            }\r
+        }\r
+\r
+        private final InputStream getCancellableStream (final boolean isInput) throws ExecutionException\r
+        {\r
+            synchronized (createFutureLock)\r
+            {\r
+                if (hasBeenCancelled.get())\r
+                    return null;\r
+\r
+                streamFuture = executor.submit (new Callable<BufferedInputStream>()\r
+                {\r
+                    @Override\r
+                    public BufferedInputStream call() throws IOException\r
+                    {\r
+                        return new BufferedInputStream (isInput ? connection.getInputStream()\r
+                                                                : connection.getErrorStream());\r
+                    }\r
+                });\r
+            }\r
+\r
+            try\r
+            {\r
+                return streamFuture.get();\r
+            }\r
+            catch (InterruptedException e)\r
+            {\r
+                return null;\r
+            }\r
+            catch (CancellationException e)\r
+            {\r
+                return null;\r
+            }\r
+        }\r
+\r
+        public final boolean connect()\r
+        {\r
+            boolean result = false;\r
+            int numFollowedRedirects = 0;\r
+\r
+            while (true)\r
+            {\r
+                result = doConnect();\r
+\r
+                if (! result)\r
+                    return false;\r
+\r
+                if (++numFollowedRedirects > numRedirectsToFollow)\r
+                    break;\r
+\r
+                int status = statusCode[0];\r
+\r
+                if (status == 301 || status == 302 || status == 303 || status == 307)\r
+                {\r
+                    // Assumes only one occurrence of "Location"\r
+                    int pos1 = responseHeaders.indexOf ("Location:") + 10;\r
+                    int pos2 = responseHeaders.indexOf ("\n", pos1);\r
+\r
+                    if (pos2 > pos1)\r
+                    {\r
+                        String currentLocation = connection.getURL().toString();\r
+                        String newLocation = responseHeaders.substring (pos1, pos2);\r
+\r
+                        try\r
+                        {\r
+                            // Handle newLocation whether it's absolute or relative\r
+                            URL baseUrl = new URL (currentLocation);\r
+                            URL newUrl  = new URL (baseUrl, newLocation);\r
+                            String transformedNewLocation = newUrl.toString();\r
+\r
+                            if (transformedNewLocation != currentLocation)\r
+                            {\r
+                                // Clear responseHeaders before next iteration\r
+                                responseHeaders.delete (0, responseHeaders.length());\r
+\r
+                                synchronized (createStreamLock)\r
+                                {\r
+                                    if (hasBeenCancelled.get())\r
+                                        return false;\r
+\r
+                                    connection.disconnect();\r
+\r
+                                    try\r
+                                    {\r
+                                        connection = createConnection (transformedNewLocation, isPost,\r
+                                                                       postData, headers, timeOutMs,\r
+                                                                       httpRequestCmd);\r
+                                    }\r
+                                    catch (Throwable e)\r
+                                    {\r
+                                        return false;\r
+                                    }\r
+                                }\r
+                            }\r
+                            else\r
+                            {\r
+                                break;\r
+                            }\r
+                        }\r
+                        catch (Throwable e)\r
+                        {\r
+                            return false;\r
+                        }\r
+                    }\r
+                    else\r
+                    {\r
+                        break;\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    break;\r
+                }\r
+            }\r
+\r
+            return result;\r
+        }\r
+\r
+        private final boolean doConnect()\r
+        {\r
+            synchronized (createStreamLock)\r
+            {\r
+                if (hasBeenCancelled.get())\r
+                    return false;\r
+\r
+                try\r
+                {\r
+                    try\r
+                    {\r
+                        inputStream = getCancellableStream (true);\r
+                    }\r
+                    catch (ExecutionException e)\r
+                    {\r
+                        if (connection.getResponseCode() < 400)\r
+                        {\r
+                            statusCode[0] = connection.getResponseCode();\r
+                            connection.disconnect();\r
+                            return false;\r
+                        }\r
+                    }\r
+                    finally\r
+                    {\r
+                        statusCode[0] = connection.getResponseCode();\r
+                    }\r
+\r
+                    try\r
+                    {\r
+                        if (statusCode[0] >= 400)\r
+                            inputStream = getCancellableStream (false);\r
+                        else\r
+                            inputStream = getCancellableStream (true);\r
+                    }\r
+                    catch (ExecutionException e)\r
+                    {}\r
+\r
+                    for (java.util.Map.Entry<String, java.util.List<String>> entry : connection.getHeaderFields().entrySet())\r
+                    {\r
+                        if (entry.getKey() != null && entry.getValue() != null)\r
+                        {\r
+                            responseHeaders.append(entry.getKey() + ": "\r
+                                                   + android.text.TextUtils.join(",", entry.getValue()) + "\n");\r
+\r
+                            if (entry.getKey().compareTo ("Content-Length") == 0)\r
+                                totalLength = Integer.decode (entry.getValue().get (0));\r
+                        }\r
+                    }\r
+\r
+                    return true;\r
+                }\r
+                catch (IOException e)\r
+                {\r
+                    return false;\r
+                }\r
+            }\r
+        }\r
+\r
+        static class DisconnectionRunnable implements Runnable\r
+        {\r
+            public DisconnectionRunnable (HttpURLConnection theConnection,\r
+                                          InputStream theInputStream,\r
+                                          ReentrantLock theCreateStreamLock,\r
+                                          Object theCreateFutureLock,\r
+                                          Future<BufferedInputStream> theStreamFuture)\r
+            {\r
+                connectionToDisconnect = theConnection;\r
+                inputStream = theInputStream;\r
+                createStreamLock = theCreateStreamLock;\r
+                createFutureLock = theCreateFutureLock;\r
+                streamFuture = theStreamFuture;\r
+            }\r
+\r
+            public void run()\r
+            {\r
+                try\r
+                {\r
+                    if (! createStreamLock.tryLock())\r
+                    {\r
+                        synchronized (createFutureLock)\r
+                        {\r
+                            if (streamFuture != null)\r
+                                streamFuture.cancel (true);\r
+                        }\r
+\r
+                        createStreamLock.lock();\r
+                    }\r
+\r
+                    if (connectionToDisconnect != null)\r
+                        connectionToDisconnect.disconnect();\r
+\r
+                    if (inputStream != null)\r
+                        inputStream.close();\r
+                }\r
+                catch (IOException e)\r
+                {}\r
+                finally\r
+                {\r
+                    createStreamLock.unlock();\r
+                }\r
+            }\r
+\r
+            private HttpURLConnection connectionToDisconnect;\r
+            private InputStream inputStream;\r
+            private ReentrantLock createStreamLock;\r
+            private Object createFutureLock;\r
+            Future<BufferedInputStream> streamFuture;\r
+        }\r
+\r
+        public final void release()\r
+        {\r
+            DisconnectionRunnable disconnectionRunnable = new DisconnectionRunnable (connection,\r
+                                                                                     inputStream,\r
+                                                                                     createStreamLock,\r
+                                                                                     createFutureLock,\r
+                                                                                     streamFuture);\r
+\r
+            synchronized (createStreamLock)\r
+            {\r
+                hasBeenCancelled.set (true);\r
+\r
+                connection = null;\r
+            }\r
+\r
+            Thread disconnectionThread = new Thread(disconnectionRunnable);\r
+            disconnectionThread.start();\r
+        }\r
+\r
+        public final int read (byte[] buffer, int numBytes)\r
+        {\r
+            int num = 0;\r
+\r
+            try\r
+            {\r
+                synchronized (createStreamLock)\r
+                {\r
+                    if (inputStream != null)\r
+                        num = inputStream.read (buffer, 0, numBytes);\r
+                }\r
+            }\r
+            catch (IOException e)\r
+            {}\r
+\r
+            if (num > 0)\r
+                position += num;\r
+\r
+            return num;\r
+        }\r
+\r
+        public final long getPosition()                 { return position; }\r
+        public final long getTotalLength()              { return totalLength; }\r
+        public final boolean isExhausted()              { return false; }\r
+        public final boolean setPosition (long newPos)  { return false; }\r
+\r
+        private boolean isPost;\r
+        private byte[] postData;\r
+        private String headers;\r
+        private int timeOutMs;\r
+        String httpRequestCmd;\r
+        private HttpURLConnection connection;\r
+        private int[] statusCode;\r
+        private StringBuffer responseHeaders;\r
+        private int totalLength;\r
+        private int numRedirectsToFollow;\r
+        private InputStream inputStream;\r
+        private long position;\r
+        private final ReentrantLock createStreamLock = new ReentrantLock();\r
+        private final Object createFutureLock = new Object();\r
+        private AtomicBoolean hasBeenCancelled = new AtomicBoolean();\r
+\r
+        private final ExecutorService executor = Executors.newCachedThreadPool (Executors.defaultThreadFactory());\r
+        Future<BufferedInputStream> streamFuture;\r
+    }\r
+\r
+    public static final HTTPStream createHTTPStream (String address, boolean isPost, byte[] postData,\r
+                                                     String headers, int timeOutMs, int[] statusCode,\r
+                                                     StringBuffer responseHeaders, int numRedirectsToFollow,\r
+                                                     String httpRequestCmd)\r
+    {\r
+        // timeout parameter of zero for HttpUrlConnection is a blocking connect (negative value for juce::URL)\r
+        if (timeOutMs < 0)\r
+            timeOutMs = 0;\r
+        else if (timeOutMs == 0)\r
+            timeOutMs = 30000;\r
+\r
+        for (;;)\r
+        {\r
+            try\r
+            {\r
+                HTTPStream httpStream = new HTTPStream (address, isPost, postData, headers,\r
+                                                        timeOutMs, statusCode, responseHeaders,\r
+                                                        numRedirectsToFollow, httpRequestCmd);\r
+\r
+                return httpStream;\r
+            }\r
+            catch (Throwable e) {}\r
+\r
+            return null;\r
+        }\r
+    }\r
+\r
+    public final void launchURL (String url)\r
+    {\r
+        startActivity (new Intent (Intent.ACTION_VIEW, Uri.parse (url)));\r
+    }\r
+\r
+    private native boolean webViewPageLoadStarted (long host, WebView view, String url);\r
+    private native void webViewPageLoadFinished (long host, WebView view, String url);\r
+    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);\r
+    private native void webViewCloseWindowRequest (long host, WebView view);\r
+    private native void webViewCreateWindowRequest (long host, WebView view);\r
+\r
+    //==============================================================================\r
+    public class JuceWebViewClient   extends WebViewClient\r
+    {\r
+        public JuceWebViewClient (long hostToUse)\r
+        {\r
+            host = hostToUse;\r
+        }\r
+\r
+        public void hostDeleted()\r
+        {\r
+            synchronized (hostLock)\r
+            {\r
+                host = 0;\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void onPageFinished (WebView view, String url)\r
+        {\r
+            if (host == 0)\r
+                return;\r
+\r
+            webViewPageLoadFinished (host, view, url);\r
+        }\r
+\r
+        @Override\r
+        public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error)\r
+        {\r
+            if (host == 0)\r
+                return;\r
+\r
+            webViewReceivedSslError (host, view, handler, error);\r
+        }\r
+\r
+        @Override\r
+        public void onReceivedError (WebView view, WebResourceRequest request, WebResourceError error)\r
+        {\r
+            if (host == 0)\r
+                return;\r
+\r
+            webViewReceivedError (host, view, request, error);\r
+        }\r
+\r
+        @Override\r
+        public void onReceivedHttpError (WebView view, WebResourceRequest request, WebResourceResponse errorResponse)\r
+        {\r
+            if (host == 0)\r
+                return;\r
+\r
+            webViewReceivedHttpError (host, view, request, errorResponse);\r
+        }\r
+\r
+        @Override\r
+        public WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request)\r
+        {\r
+            synchronized (hostLock)\r
+            {\r
+                if (host != 0)\r
+                {\r
+                    boolean shouldLoad = webViewPageLoadStarted (host, view, request.getUrl().toString());\r
+\r
+                    if (shouldLoad)\r
+                        return null;\r
+                }\r
+            }\r
+\r
+            return new WebResourceResponse ("text/html", null, null);\r
+        }\r
+\r
+        private long host;\r
+        private final Object hostLock = new Object();\r
+    }\r
+\r
+    public class JuceWebChromeClient    extends WebChromeClient\r
+    {\r
+        public JuceWebChromeClient (long hostToUse)\r
+        {\r
+            host = hostToUse;\r
+        }\r
+\r
+        @Override\r
+        public void onCloseWindow (WebView window)\r
+        {\r
+            webViewCloseWindowRequest (host, window);\r
+        }\r
+\r
+        @Override\r
+        public boolean onCreateWindow (WebView view, boolean isDialog,\r
+                                       boolean isUserGesture, Message resultMsg)\r
+        {\r
+            webViewCreateWindowRequest (host, view);\r
+            return false;\r
+        }\r
+\r
+        private long host;\r
+        private final Object hostLock = new Object();\r
+    }\r
+\r
+    //==============================================================================\r
+    public static final String getLocaleValue (boolean isRegion)\r
+    {\r
+        java.util.Locale locale = java.util.Locale.getDefault();\r
+\r
+        return isRegion ? locale.getCountry()\r
+                        : locale.getLanguage();\r
+    }\r
+\r
+    private static final String getFileLocation (String type)\r
+    {\r
+        return Environment.getExternalStoragePublicDirectory (type).getAbsolutePath();\r
+    }\r
+\r
+    public static final String getDocumentsFolder()\r
+    {\r
+        if (getAndroidSDKVersion() >= 19)\r
+            return getFileLocation ("Documents");\r
+\r
+        return Environment.getDataDirectory().getAbsolutePath();\r
+    }\r
+\r
+    public static final String getPicturesFolder()   { return getFileLocation (Environment.DIRECTORY_PICTURES); }\r
+    public static final String getMusicFolder()      { return getFileLocation (Environment.DIRECTORY_MUSIC); }\r
+    public static final String getMoviesFolder()     { return getFileLocation (Environment.DIRECTORY_MOVIES); }\r
+    public static final String getDownloadsFolder()  { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); }\r
+\r
+    //==============================================================================\r
+    @Override\r
+    protected void onActivityResult (int requestCode, int resultCode, Intent data)\r
+    {\r
+        appActivityResult (requestCode, resultCode, data);\r
+    }\r
+\r
+    @Override\r
+    protected void onNewIntent (Intent intent)\r
+    {\r
+        super.onNewIntent(intent);\r
+        setIntent(intent);\r
+\r
+        appNewIntent (intent);\r
+    }\r
+\r
+    //==============================================================================\r
+    public final Typeface getTypeFaceFromAsset (String assetName)\r
+    {\r
+        try\r
+        {\r
+            return Typeface.createFromAsset (this.getResources().getAssets(), assetName);\r
+        }\r
+        catch (Throwable e) {}\r
+\r
+        return null;\r
+    }\r
+\r
+    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();\r
+\r
+    public static String bytesToHex (byte[] bytes)\r
+    {\r
+        char[] hexChars = new char[bytes.length * 2];\r
+\r
+        for (int j = 0; j < bytes.length; ++j)\r
+        {\r
+            int v = bytes[j] & 0xff;\r
+            hexChars[j * 2]     = hexArray[v >>> 4];\r
+            hexChars[j * 2 + 1] = hexArray[v & 0x0f];\r
+        }\r
+\r
+        return new String (hexChars);\r
+    }\r
+\r
+    final private java.util.Map dataCache = new java.util.HashMap();\r
+\r
+    synchronized private final File getDataCacheFile (byte[] data)\r
+    {\r
+        try\r
+        {\r
+            java.security.MessageDigest digest = java.security.MessageDigest.getInstance ("MD5");\r
+            digest.update (data);\r
+\r
+            String key = bytesToHex (digest.digest());\r
+\r
+            if (dataCache.containsKey (key))\r
+                return (File) dataCache.get (key);\r
+\r
+            File f = new File (this.getCacheDir(), "bindata_" + key);\r
+            f.delete();\r
+            FileOutputStream os = new FileOutputStream (f);\r
+            os.write (data, 0, data.length);\r
+            dataCache.put (key, f);\r
+            return f;\r
+        }\r
+        catch (Throwable e) {}\r
+\r
+        return null;\r
+    }\r
+\r
+    private final void clearDataCache()\r
+    {\r
+        java.util.Iterator it = dataCache.values().iterator();\r
+\r
+        while (it.hasNext())\r
+        {\r
+            File f = (File) it.next();\r
+            f.delete();\r
+        }\r
+    }\r
+\r
+    public final Typeface getTypeFaceFromByteArray (byte[] data)\r
+    {\r
+        try\r
+        {\r
+            File f = getDataCacheFile (data);\r
+\r
+            if (f != null)\r
+                return Typeface.createFromFile (f);\r
+        }\r
+        catch (Exception e)\r
+        {\r
+            Log.e ("JUCE", e.toString());\r
+        }\r
+\r
+        return null;\r
+    }\r
+\r
+    public static final int getAndroidSDKVersion()\r
+    {\r
+        return android.os.Build.VERSION.SDK_INT;\r
+    }\r
+\r
+    public final String audioManagerGetProperty (String property)\r
+    {\r
+        Object obj = getSystemService (AUDIO_SERVICE);\r
+        if (obj == null)\r
+            return null;\r
+\r
+        java.lang.reflect.Method method;\r
+\r
+        try\r
+        {\r
+            method = obj.getClass().getMethod ("getProperty", String.class);\r
+        }\r
+        catch (SecurityException e)     { return null; }\r
+        catch (NoSuchMethodException e) { return null; }\r
+\r
+        if (method == null)\r
+            return null;\r
+\r
+        try\r
+        {\r
+            return (String) method.invoke (obj, property);\r
+        }\r
+        catch (java.lang.IllegalArgumentException e) {}\r
+        catch (java.lang.IllegalAccessException e) {}\r
+        catch (java.lang.reflect.InvocationTargetException e) {}\r
+\r
+        return null;\r
+    }\r
+\r
+    public final boolean hasSystemFeature (String property)\r
+    {\r
+        return getPackageManager().hasSystemFeature (property);\r
+    }\r
+}\r
diff --git a/extras/AudioPluginHost/Builds/Android/app/src/main/java/com/roli/juce/pluginhost/SharingContentProvider.java b/extras/AudioPluginHost/Builds/Android/app/src/main/java/com/roli/juce/pluginhost/SharingContentProvider.java
new file mode 100644 (file)
index 0000000..f8dd82b
--- /dev/null
@@ -0,0 +1,138 @@
+package com.roli.juce.pluginhost;\r
+\r
+import android.content.ContentProvider;\r
+import android.content.ContentValues;\r
+import android.content.res.AssetFileDescriptor;\r
+import android.content.res.Resources;\r
+import android.database.Cursor;\r
+import android.database.MatrixCursor;\r
+import android.net.Uri;\r
+import android.os.FileObserver;\r
+import android.os.ParcelFileDescriptor;\r
+import java.lang.String;\r
+\r
+public final class SharingContentProvider extends ContentProvider\r
+{\r
+    private Object lock = new Object();\r
+\r
+    private native void contentSharerFileObserverEvent (long host, int event, String path);\r
+\r
+    private native Cursor contentSharerQuery (Uri uri, String[] projection, String selection,\r
+                                              String[] selectionArgs, String sortOrder);\r
+\r
+    private native void contentSharerCursorClosed (long host);\r
+\r
+    private native AssetFileDescriptor contentSharerOpenFile (Uri uri, String mode);\r
+    private native String[] contentSharerGetStreamTypes (Uri uri, String mimeTypeFilter);\r
+\r
+    public final class ProviderFileObserver extends FileObserver\r
+    {\r
+        public ProviderFileObserver (long hostToUse, String path, int mask)\r
+        {\r
+            super (path, mask);\r
+\r
+            host = hostToUse;\r
+        }\r
+\r
+        public void onEvent (int event, String path)\r
+        {\r
+            contentSharerFileObserverEvent (host, event, path);\r
+        }\r
+\r
+        private long host;\r
+    }\r
+\r
+    public final class ProviderCursor extends MatrixCursor\r
+    {\r
+        ProviderCursor (long hostToUse, String[] columnNames)\r
+        {\r
+            super (columnNames);\r
+\r
+            host = hostToUse;\r
+        }\r
+\r
+        @Override\r
+        public void close()\r
+        {\r
+            super.close();\r
+\r
+            contentSharerCursorClosed (host);\r
+        }\r
+\r
+        private long host;\r
+    }\r
+\r
+    @Override\r
+    public boolean onCreate()\r
+    {\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public Cursor query (Uri url, String[] projection, String selection,\r
+                         String[] selectionArgs, String sortOrder)\r
+    {\r
+        synchronized (lock)\r
+        {\r
+            return contentSharerQuery (url, projection, selection, selectionArgs, sortOrder);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public Uri insert (Uri uri, ContentValues values)\r
+    {\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public int update (Uri uri, ContentValues values, String selection,\r
+                       String[] selectionArgs)\r
+    {\r
+        return 0;\r
+    }\r
+\r
+    @Override\r
+    public int delete (Uri uri, String selection, String[] selectionArgs)\r
+    {\r
+        return 0;\r
+    }\r
+\r
+    @Override\r
+    public String getType (Uri uri)\r
+    {\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public AssetFileDescriptor openAssetFile (Uri uri, String mode)\r
+    {\r
+        synchronized (lock)\r
+        {\r
+            return contentSharerOpenFile (uri, mode);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ParcelFileDescriptor openFile (Uri uri, String mode)\r
+    {\r
+        synchronized (lock)\r
+        {\r
+            AssetFileDescriptor result = contentSharerOpenFile (uri, mode);\r
+\r
+            if (result != null)\r
+                return result.getParcelFileDescriptor();\r
+\r
+            return null;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public String[] getStreamTypes (Uri uri, String mimeTypeFilter)\r
+    {\r
+        synchronized (lock)\r
+        {\r
+            return contentSharerGetStreamTypes (uri, mimeTypeFilter);\r
+        }\r
+    }\r
+\r
+}\r
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
new file mode 100644 (file)
index 0000000..e551340
Binary files /dev/null and b/extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-hdpi/icon.png differ
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
new file mode 100644 (file)
index 0000000..475d142
Binary files /dev/null and b/extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-ldpi/icon.png differ
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
new file mode 100644 (file)
index 0000000..eb13005
Binary files /dev/null and b/extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-mdpi/icon.png differ
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
new file mode 100644 (file)
index 0000000..dddc790
Binary files /dev/null and b/extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-xhdpi/icon.png differ
diff --git a/extras/AudioPluginHost/Builds/Android/app/src/release/res/values/string.xml b/extras/AudioPluginHost/Builds/Android/app/src/release/res/values/string.xml
new file mode 100644 (file)
index 0000000..bed17a5
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<resources>
+  <string name="app_name">AudioPluginHost</string>
+</resources>
diff --git a/extras/AudioPluginHost/Builds/Android/build.gradle b/extras/AudioPluginHost/Builds/Android/build.gradle
new file mode 100644 (file)
index 0000000..651d63d
--- /dev/null
@@ -0,0 +1,16 @@
+buildscript {\r
+   repositories {\r
+       google()\r
+       jcenter()\r
+   }\r
+   dependencies {\r
+       classpath 'com.android.tools.build:gradle:3.1.1'\r
+   }\r
+}\r
+\r
+allprojects {\r
+   repositories {\r
+       google()\r
+       jcenter()\r
+   }\r
+}\r
diff --git a/extras/AudioPluginHost/Builds/Android/gradle/wrapper/LICENSE-for-gradlewrapper.txt b/extras/AudioPluginHost/Builds/Android/gradle/wrapper/LICENSE-for-gradlewrapper.txt
new file mode 100644 (file)
index 0000000..e06d208
--- /dev/null
@@ -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/extras/AudioPluginHost/Builds/Android/gradle/wrapper/gradle-wrapper.jar b/extras/AudioPluginHost/Builds/Android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644 (file)
index 0000000..13372ae
Binary files /dev/null and b/extras/AudioPluginHost/Builds/Android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/extras/AudioPluginHost/Builds/Android/gradle/wrapper/gradle-wrapper.properties b/extras/AudioPluginHost/Builds/Android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644 (file)
index 0000000..d384d28
--- /dev/null
@@ -0,0 +1 @@
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
\ No newline at end of file
diff --git a/extras/AudioPluginHost/Builds/Android/gradlew b/extras/AudioPluginHost/Builds/Android/gradlew
new file mode 100755 (executable)
index 0000000..9d82f78
--- /dev/null
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/extras/AudioPluginHost/Builds/Android/gradlew.bat b/extras/AudioPluginHost/Builds/Android/gradlew.bat
new file mode 100644 (file)
index 0000000..aec9973
--- /dev/null
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off\r
+@rem ##########################################################################\r
+@rem\r
+@rem  Gradle startup script for Windows\r
+@rem\r
+@rem ##########################################################################\r
+\r
+@rem Set local scope for the variables with windows NT shell\r
+if "%OS%"=="Windows_NT" setlocal\r
+\r
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r
+set DEFAULT_JVM_OPTS=\r
+\r
+set DIRNAME=%~dp0\r
+if "%DIRNAME%" == "" set DIRNAME=.\r
+set APP_BASE_NAME=%~n0\r
+set APP_HOME=%DIRNAME%\r
+\r
+@rem Find java.exe\r
+if defined JAVA_HOME goto findJavaFromJavaHome\r
+\r
+set JAVA_EXE=java.exe\r
+%JAVA_EXE% -version >NUL 2>&1\r
+if "%ERRORLEVEL%" == "0" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:findJavaFromJavaHome\r
+set JAVA_HOME=%JAVA_HOME:"=%\r
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r
+\r
+if exist "%JAVA_EXE%" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:init\r
+@rem Get command-line arguments, handling Windowz variants\r
+\r
+if not "%OS%" == "Windows_NT" goto win9xME_args\r
+if "%@eval[2+2]" == "4" goto 4NT_args\r
+\r
+:win9xME_args\r
+@rem Slurp the command line arguments.\r
+set CMD_LINE_ARGS=\r
+set _SKIP=2\r
+\r
+:win9xME_args_slurp\r
+if "x%~1" == "x" goto execute\r
+\r
+set CMD_LINE_ARGS=%*\r
+goto execute\r
+\r
+:4NT_args\r
+@rem Get arguments from the 4NT Shell from JP Software\r
+set CMD_LINE_ARGS=%$\r
+\r
+:execute\r
+@rem Setup the command line\r
+\r
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar\r
+\r
+@rem Execute Gradle\r
+"%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
+\r
+:end\r
+@rem End local scope for the variables with windows NT shell\r
+if "%ERRORLEVEL%"=="0" goto mainEnd\r
+\r
+:fail\r
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r
+rem the _cmd.exe /c_ return code!\r
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1\r
+exit /b 1\r
+\r
+:mainEnd\r
+if "%OS%"=="Windows_NT" endlocal\r
+\r
+:omega\r
diff --git a/extras/AudioPluginHost/Builds/Android/settings.gradle b/extras/AudioPluginHost/Builds/Android/settings.gradle
new file mode 100644 (file)
index 0000000..9d495b3
--- /dev/null
@@ -0,0 +1 @@
+include ':app'
\ No newline at end of file
index f22468b4dd9870f21942d05dad227e4923ff3072..2d619282be2b1e4fad11aa15991829e7920ef66f 100644 (file)
@@ -35,7 +35,7 @@ ifeq ($(CONFIG),Debug)
     TARGET_ARCH := -march=native\r
   endif\r
 \r
-  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 freetype2 libcurl x11 xext xinerama) -pthread -I$(HOME)/SDKs/VST_SDK/VST3_SDK -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)\r
+  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 freetype2 libcurl x11 xext xinerama) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)\r
   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
   JUCE_TARGET_APP := AudioPluginHost\r
 \r
@@ -56,7 +56,7 @@ ifeq ($(CONFIG),Release)
     TARGET_ARCH := -march=native\r
   endif\r
 \r
-  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 freetype2 libcurl x11 xext xinerama) -pthread -I$(HOME)/SDKs/VST_SDK/VST3_SDK -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)\r
+  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 freetype2 libcurl x11 xext xinerama) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)\r
   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
   JUCE_TARGET_APP := AudioPluginHost\r
 \r
@@ -68,12 +68,13 @@ ifeq ($(CONFIG),Release)
 endif\r
 \r
 OBJECTS_APP := \\r
-  $(JUCE_OBJDIR)/FilterGraph_62e9c017.o \\r
-  $(JUCE_OBJDIR)/FilterIOConfiguration_1cc9b659.o \\r
-  $(JUCE_OBJDIR)/GraphEditorPanel_3dbd4872.o \\r
+  $(JUCE_OBJDIR)/FilterGraph_769715e3.o \\r
+  $(JUCE_OBJDIR)/FilterIOConfiguration_d1cf3d25.o \\r
+  $(JUCE_OBJDIR)/InternalFilters_eceadbab.o \\r
+  $(JUCE_OBJDIR)/GraphEditorPanel_2223d925.o \\r
+  $(JUCE_OBJDIR)/MainHostWindow_b3494acd.o \\r
   $(JUCE_OBJDIR)/HostStartup_5ce96f96.o \\r
-  $(JUCE_OBJDIR)/InternalFilters_beb54bdf.o \\r
-  $(JUCE_OBJDIR)/MainHostWindow_e920295a.o \\r
+  $(JUCE_OBJDIR)/BinaryData_ce4232d4.o \\r
   $(JUCE_OBJDIR)/include_juce_audio_basics_8a4e984a.o \\r
   $(JUCE_OBJDIR)/include_juce_audio_devices_63111d02.o \\r
   $(JUCE_OBJDIR)/include_juce_audio_formats_15f82001.o \\r
@@ -100,34 +101,39 @@ $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) : check-pkg-config $(OBJECTS_APP) $(RESOURCES)
        -$(V_AT)mkdir -p $(JUCE_OUTDIR)\r
        $(V_AT)$(CXX) -o $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(OBJECTS_APP) $(JUCE_LDFLAGS) $(JUCE_LDFLAGS_APP) $(RESOURCES) $(TARGET_ARCH)\r
 \r
-$(JUCE_OBJDIR)/FilterGraph_62e9c017.o: ../../Source/FilterGraph.cpp\r
+$(JUCE_OBJDIR)/FilterGraph_769715e3.o: ../../Source/Filters/FilterGraph.cpp\r
        -$(V_AT)mkdir -p $(JUCE_OBJDIR)\r
        @echo "Compiling FilterGraph.cpp"\r
        $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"\r
 \r
-$(JUCE_OBJDIR)/FilterIOConfiguration_1cc9b659.o: ../../Source/FilterIOConfiguration.cpp\r
+$(JUCE_OBJDIR)/FilterIOConfiguration_d1cf3d25.o: ../../Source/Filters/FilterIOConfiguration.cpp\r
        -$(V_AT)mkdir -p $(JUCE_OBJDIR)\r
        @echo "Compiling FilterIOConfiguration.cpp"\r
        $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"\r
 \r
-$(JUCE_OBJDIR)/GraphEditorPanel_3dbd4872.o: ../../Source/GraphEditorPanel.cpp\r
+$(JUCE_OBJDIR)/InternalFilters_eceadbab.o: ../../Source/Filters/InternalFilters.cpp\r
+       -$(V_AT)mkdir -p $(JUCE_OBJDIR)\r
+       @echo "Compiling InternalFilters.cpp"\r
+       $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"\r
+\r
+$(JUCE_OBJDIR)/GraphEditorPanel_2223d925.o: ../../Source/UI/GraphEditorPanel.cpp\r
        -$(V_AT)mkdir -p $(JUCE_OBJDIR)\r
        @echo "Compiling GraphEditorPanel.cpp"\r
        $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"\r
 \r
-$(JUCE_OBJDIR)/HostStartup_5ce96f96.o: ../../Source/HostStartup.cpp\r
+$(JUCE_OBJDIR)/MainHostWindow_b3494acd.o: ../../Source/UI/MainHostWindow.cpp\r
        -$(V_AT)mkdir -p $(JUCE_OBJDIR)\r
-       @echo "Compiling HostStartup.cpp"\r
+       @echo "Compiling MainHostWindow.cpp"\r
        $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"\r
 \r
-$(JUCE_OBJDIR)/InternalFilters_beb54bdf.o: ../../Source/InternalFilters.cpp\r
+$(JUCE_OBJDIR)/HostStartup_5ce96f96.o: ../../Source/HostStartup.cpp\r
        -$(V_AT)mkdir -p $(JUCE_OBJDIR)\r
-       @echo "Compiling InternalFilters.cpp"\r
+       @echo "Compiling HostStartup.cpp"\r
        $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"\r
 \r
-$(JUCE_OBJDIR)/MainHostWindow_e920295a.o: ../../Source/MainHostWindow.cpp\r
+$(JUCE_OBJDIR)/BinaryData_ce4232d4.o: ../../JuceLibraryCode/BinaryData.cpp\r
        -$(V_AT)mkdir -p $(JUCE_OBJDIR)\r
-       @echo "Compiling MainHostWindow.cpp"\r
+       @echo "Compiling BinaryData.cpp"\r
        $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"\r
 \r
 $(JUCE_OBJDIR)/include_juce_audio_basics_8a4e984a.o: ../../JuceLibraryCode/include_juce_audio_basics.cpp\r
index 741092696b68fc26bb100194419ec789a4430c24..8fe60e822099d9f93ecc2b9e0ac17628ba9f5542 100644 (file)
                A02C9F4C4B840C27B6CAFEBD = {isa = PBXBuildFile; fileRef = 89309C0C5F3269BD06BE7F27; };
                4DB15177DDC357F4503F88CF = {isa = PBXBuildFile; fileRef = B457EE687507BF1DEEA7581F; };
                D92C7BF86C9CCF6B4D14F809 = {isa = PBXBuildFile; fileRef = 7DA35787B5F6F7440D667CC8; };
-               4C88899EB7993A76A97643FE = {isa = PBXBuildFile; fileRef = 9BA1DD697B98005D24F7EC3C; };
-               485A37478F7EAA352DD1A86A = {isa = PBXBuildFile; fileRef = 01FE7ED58992BC9683BA3C94; };
-               040EB574807E8A86F124D851 = {isa = PBXBuildFile; fileRef = B1C6B9E4B9FDC17AA298E541; };
+               443244451A0F2064D4767337 = {isa = PBXBuildFile; fileRef = 2A6983F82B13F9E8B10299AE; };
+               2E74188531792924F0C73142 = {isa = PBXBuildFile; fileRef = 05863BDFC582C9552A86DF49; };
+               C8423A9611C8AAF27468847D = {isa = PBXBuildFile; fileRef = 336FD30C38BD0A176161B8AE; };
+               786AF545C1C1E4D11140C3DF = {isa = PBXBuildFile; fileRef = 43647951ECC7F030B9953965; };
+               3E1689E23B9C85F03209DCEF = {isa = PBXBuildFile; fileRef = 3D78A731234A833CA112AE45; };
+               F635D974599DEC2ED91E6A88 = {isa = PBXBuildFile; fileRef = 04AABCD3491318FB32E844B4; };
                A1B0416DA378BB0C3AD6F74B = {isa = PBXBuildFile; fileRef = A66EFAC64B1B67B536C73415; };
-               D493393499E0822C70009A63 = {isa = PBXBuildFile; fileRef = 362BB539489999164C3A3D5B; };
-               6CD3B433544911DA879170AE = {isa = PBXBuildFile; fileRef = 1EC0F33A3BABE58138317375; };
+               A0144A682BF4843C8CF53FE4 = {isa = PBXBuildFile; fileRef = 6D107D7946DC5976B766345B; };
                15CCE43D7DCFC649638919D4 = {isa = PBXBuildFile; fileRef = 4C7D82F9274A4F9DBF11235C; };
                5C4D406B924230F83E3580AD = {isa = PBXBuildFile; fileRef = 65968EA1B476D71F14DE1D58; };
                F4DD98B9310B679D50A2C8A6 = {isa = PBXBuildFile; fileRef = 5D250A57C7DEA80248F30EED; };
                C38D14DC58F1941DD5E4BF60 = {isa = PBXBuildFile; fileRef = 2BE6C2DFD6EBB9A89109AEB5; };
                2727A191DB1BAAC9C04B9081 = {isa = PBXBuildFile; fileRef = 37E4D5C341406B7072120006; };
                84BAFE82A102D9C350672689 = {isa = PBXBuildFile; fileRef = 29D746FC68F69751796671A2; };
-               01FE7ED58992BC9683BA3C94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FilterIOConfiguration.cpp; path = ../../Source/FilterIOConfiguration.cpp; sourceTree = "SOURCE_ROOT"; };
-               18DD15714443AFC3BAAE211C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FilterIOConfiguration.h; path = ../../Source/FilterIOConfiguration.h; sourceTree = "SOURCE_ROOT"; };
-               1EC0F33A3BABE58138317375 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MainHostWindow.cpp; path = ../../Source/MainHostWindow.cpp; sourceTree = "SOURCE_ROOT"; };
+               04AABCD3491318FB32E844B4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MainHostWindow.cpp; path = ../../Source/UI/MainHostWindow.cpp; sourceTree = "SOURCE_ROOT"; };
+               04DB9A49969ECC740CC25665 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GraphEditorPanel.h; path = ../../Source/UI/GraphEditorPanel.h; sourceTree = "SOURCE_ROOT"; };
+               05863BDFC582C9552A86DF49 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FilterGraph.cpp; path = ../../Source/Filters/FilterGraph.cpp; sourceTree = "SOURCE_ROOT"; };
+               1DADAD8E34AAF4AFF1C69DC4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BinaryData.h; 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"; };
-               2B143B5431318DDB2104B46E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FilterGraph.h; path = ../../Source/FilterGraph.h; sourceTree = "SOURCE_ROOT"; };
+               2A6983F82B13F9E8B10299AE = {isa = PBXFileReference; lastKnownFileType = file.icns; name = Icon.icns; path = Icon.icns; sourceTree = "SOURCE_ROOT"; };
                2BE6C2DFD6EBB9A89109AEB5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_extra.mm"; path = "../../JuceLibraryCode/include_juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; };
                30F22843EFEBF7AA841EB4D6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; };
                31D55A751C790CB81F58DDB7 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
-               362BB539489999164C3A3D5B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = InternalFilters.cpp; path = ../../Source/InternalFilters.cpp; sourceTree = "SOURCE_ROOT"; };
+               336FD30C38BD0A176161B8AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FilterIOConfiguration.cpp; path = ../../Source/Filters/FilterIOConfiguration.cpp; sourceTree = "SOURCE_ROOT"; };
                37E4D5C341406B7072120006 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_opengl.mm"; path = "../../JuceLibraryCode/include_juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; };
                3C070DD522CDD11FFC87425D = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_utils"; path = "../../../../modules/juce_audio_utils"; sourceTree = "SOURCE_ROOT"; };
                3D57FE2A8877F12A61054726 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_core"; path = "../../../../modules/juce_core"; sourceTree = "SOURCE_ROOT"; };
+               3D78A731234A833CA112AE45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = GraphEditorPanel.cpp; path = ../../Source/UI/GraphEditorPanel.cpp; sourceTree = "SOURCE_ROOT"; };
+               43647951ECC7F030B9953965 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = InternalFilters.cpp; path = ../../Source/Filters/InternalFilters.cpp; sourceTree = "SOURCE_ROOT"; };
                4C7D82F9274A4F9DBF11235C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_basics.mm"; path = "../../JuceLibraryCode/include_juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; };
                4DF6E6E41E10965AD169143B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
                5313EB852E41EE58B199B9A2 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_devices"; path = "../../../../modules/juce_audio_devices"; sourceTree = "SOURCE_ROOT"; };
+               545D57A6AA801B38548B0CAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FilterGraph.h; path = ../../Source/Filters/FilterGraph.h; sourceTree = "SOURCE_ROOT"; };
                57DF618F1DE781556B7AFC32 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-App.plist"; path = "Info-App.plist"; sourceTree = "SOURCE_ROOT"; };
                59842A98E5EBBC54B50C04CD = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_events"; path = "../../../../modules/juce_events"; sourceTree = "SOURCE_ROOT"; };
                5ACC21AA45BBF48C3C64D56D = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
                5EF1D381F42AA8764597F189 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_data_structures.mm"; path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
                5FBD6C402617272052BB4D81 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_processors.mm"; path = "../../JuceLibraryCode/include_juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; };
                65968EA1B476D71F14DE1D58 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_devices.mm"; path = "../../JuceLibraryCode/include_juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; };
-               6692043E22BB181F01767845 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MainHostWindow.h; path = ../../Source/MainHostWindow.h; sourceTree = "SOURCE_ROOT"; };
                683CEE986A2467C850FE99E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_core.mm"; path = "../../JuceLibraryCode/include_juce_core.mm"; sourceTree = "SOURCE_ROOT"; };
                6A71B2BCAC4239072BC2BD7E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_basics"; path = "../../../../modules/juce_audio_basics"; sourceTree = "SOURCE_ROOT"; };
-               714C53257417E615916687E5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PluginWindow.h; path = ../../Source/PluginWindow.h; sourceTree = "SOURCE_ROOT"; };
+               6D107D7946DC5976B766345B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = BinaryData.cpp; path = ../../JuceLibraryCode/BinaryData.cpp; sourceTree = "SOURCE_ROOT"; };
+               725D0D9C8C7FF7B3FB3020ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FilterIOConfiguration.h; path = ../../Source/Filters/FilterIOConfiguration.h; sourceTree = "SOURCE_ROOT"; };
                7DA35787B5F6F7440D667CC8 = {isa = PBXFileReference; lastKnownFileType = file.nib; name = RecentFilesMenuTemplate.nib; path = RecentFilesMenuTemplate.nib; sourceTree = "SOURCE_ROOT"; };
                81C1A7770E082F56FE5A90A7 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_opengl"; path = "../../../../modules/juce_opengl"; sourceTree = "SOURCE_ROOT"; };
                82800DBA287EF4BAB13B42FB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_graphics.mm"; path = "../../JuceLibraryCode/include_juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; };
                938AE72315C6C93949F6220E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_basics"; 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; name = "juce_graphics"; path = "../../../../modules/juce_graphics"; sourceTree = "SOURCE_ROOT"; };
+               97918AB43AD460AFA8FA2FFE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PluginWindow.h; path = ../../Source/UI/PluginWindow.h; sourceTree = "SOURCE_ROOT"; };
                9794142D24966F93FFDE51A1 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
-               9BA1DD697B98005D24F7EC3C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FilterGraph.cpp; path = ../../Source/FilterGraph.cpp; sourceTree = "SOURCE_ROOT"; };
+               9EBEE3AE5856E877478607C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InternalFilters.h; path = ../../Source/Filters/InternalFilters.h; sourceTree = "SOURCE_ROOT"; };
                9F9B445E6755CAA19E4344ED = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; 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; name = MainHostWindow.h; path = ../../Source/UI/MainHostWindow.h; sourceTree = "SOURCE_ROOT"; };
                A5E7CA8A71D049BE2BD33861 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; };
                A66EFAC64B1B67B536C73415 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = HostStartup.cpp; path = ../../Source/HostStartup.cpp; sourceTree = "SOURCE_ROOT"; };
                B0935EBBA4F6E2B05F3D1C0A = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
-               B1C6B9E4B9FDC17AA298E541 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = GraphEditorPanel.cpp; path = ../../Source/GraphEditorPanel.cpp; sourceTree = "SOURCE_ROOT"; };
                B285CAB91AE928C476CA4F9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_utils.mm"; path = "../../JuceLibraryCode/include_juce_audio_utils.mm"; sourceTree = "SOURCE_ROOT"; };
+               B2A1E626CC120982805754F6 = {isa = PBXFileReference; lastKnownFileType = image.png; name = JUCEAppIcon.png; 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; name = "juce_data_structures"; path = "../../../../modules/juce_data_structures"; sourceTree = "SOURCE_ROOT"; };
                B8774D8AD307D798831C0DF7 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiscRecording.framework; path = System/Library/Frameworks/DiscRecording.framework; sourceTree = SDKROOT; };
                B8E24A5CEE6B7055537725CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_cryptography.mm"; path = "../../JuceLibraryCode/include_juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; };
                D313CF37B25D7FD313C4F336 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
                D4EBC17BDB7F88CCBC76730B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
-               DD8E5D0C88FA2C287F824357 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GraphEditorPanel.h; path = ../../Source/GraphEditorPanel.h; sourceTree = "SOURCE_ROOT"; };
                DDE115D3084ACA6DD6AA4471 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_video"; path = "../../../../modules/juce_video"; sourceTree = "SOURCE_ROOT"; };
                E68018DE199135B7F738FB17 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioKit.framework; path = System/Library/Frameworks/CoreAudioKit.framework; sourceTree = SDKROOT; };
-               EE1BEF4055936CD0C543687C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InternalFilters.h; path = ../../Source/InternalFilters.h; sourceTree = "SOURCE_ROOT"; };
                F299BECFB2AEA6105F014848 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_extra"; path = "../../../../modules/juce_gui_extra"; sourceTree = "SOURCE_ROOT"; };
                F9AC862E9A3583B6C1488EE0 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_formats"; path = "../../../../modules/juce_audio_formats"; sourceTree = "SOURCE_ROOT"; };
                FA21631C5536EA3DF55C7FA6 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_cryptography"; path = "../../../../modules/juce_cryptography"; sourceTree = "SOURCE_ROOT"; };
                FAF867E9E731D0880D40511F = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_processors"; path = "../../../../modules/juce_audio_processors"; sourceTree = "SOURCE_ROOT"; };
-               97790EAEA01CFA5C3CA9737A = {isa = PBXGroup; children = (
-                                       9BA1DD697B98005D24F7EC3C,
-                                       2B143B5431318DDB2104B46E,
-                                       01FE7ED58992BC9683BA3C94,
-                                       18DD15714443AFC3BAAE211C,
-                                       B1C6B9E4B9FDC17AA298E541,
-                                       DD8E5D0C88FA2C287F824357,
+               AA37F82D57C9BB4BE78FCCB9 = {isa = PBXGroup; children = (
+                                       05863BDFC582C9552A86DF49,
+                                       545D57A6AA801B38548B0CAC,
+                                       336FD30C38BD0A176161B8AE,
+                                       725D0D9C8C7FF7B3FB3020ED,
+                                       43647951ECC7F030B9953965,
+                                       9EBEE3AE5856E877478607C7, ); name = Filters; sourceTree = "<group>"; };
+               DE7B77306553B1204071B39A = {isa = PBXGroup; children = (
+                                       3D78A731234A833CA112AE45,
+                                       04DB9A49969ECC740CC25665,
+                                       04AABCD3491318FB32E844B4,
+                                       A5DFC13E4F09134B0D226A3E,
+                                       97918AB43AD460AFA8FA2FFE, ); name = UI; sourceTree = "<group>"; };
+               B225B7F2CAABD28A41E7C339 = {isa = PBXGroup; children = (
+                                       AA37F82D57C9BB4BE78FCCB9,
+                                       DE7B77306553B1204071B39A,
                                        A66EFAC64B1B67B536C73415,
-                                       362BB539489999164C3A3D5B,
-                                       EE1BEF4055936CD0C543687C,
-                                       1EC0F33A3BABE58138317375,
-                                       6692043E22BB181F01767845,
-                                       714C53257417E615916687E5, ); name = AudioPluginHost; sourceTree = "<group>"; };
+                                       B2A1E626CC120982805754F6, ); name = Source; sourceTree = "<group>"; };
+               97790EAEA01CFA5C3CA9737A = {isa = PBXGroup; children = (
+                                       B225B7F2CAABD28A41E7C339, ); name = AudioPluginHost; sourceTree = "<group>"; };
                9D8FE1F65CAD416AA606C47A = {isa = PBXGroup; children = (
                                        6A71B2BCAC4239072BC2BD7E,
                                        5313EB852E41EE58B199B9A2,
                                        DDE115D3084ACA6DD6AA4471, ); name = "JUCE Modules"; sourceTree = "<group>"; };
                7E30376DDAD775FEFE64944C = {isa = PBXGroup; children = (
                                        30F22843EFEBF7AA841EB4D6,
+                                       6D107D7946DC5976B766345B,
+                                       1DADAD8E34AAF4AFF1C69DC4,
                                        4C7D82F9274A4F9DBF11235C,
                                        65968EA1B476D71F14DE1D58,
                                        5D250A57C7DEA80248F30EED,
                                        A5E7CA8A71D049BE2BD33861, ); name = "JUCE Library Code"; sourceTree = "<group>"; };
                A97EE73C79DA3F729D46AF48 = {isa = PBXGroup; children = (
                                        57DF618F1DE781556B7AFC32,
-                                       7DA35787B5F6F7440D667CC8, ); name = Resources; sourceTree = "<group>"; };
+                                       7DA35787B5F6F7440D667CC8,
+                                       2A6983F82B13F9E8B10299AE, ); name = Resources; sourceTree = "<group>"; };
                D1C4804CD275CB57A5C89A2D = {isa = PBXGroup; children = (
                                        86CA337014D3F67E906FFD28,
                                        D4EBC17BDB7F88CCBC76730B,
                                MACOSX_DEPLOYMENT_TARGET = 10.11;
                                MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
                                OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wstrict-aliasing -Wconversion -Wsign-compare -Woverloaded-virtual -Wextra-semi";
-                               PRODUCT_BUNDLE_IDENTIFIER = com.roli.pluginhost;
+                               PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.pluginhost;
                                SDKROOT_ppc = macosx10.5;
                                USE_HEADERMAP = NO; }; name = Debug; };
                49453CC5AD9F08D2738464AC = {isa = XCBuildConfiguration; buildSettings = {
                                MACOSX_DEPLOYMENT_TARGET = 10.11;
                                MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
                                OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wstrict-aliasing -Wconversion -Wsign-compare -Woverloaded-virtual -Wextra-semi";
-                               PRODUCT_BUNDLE_IDENTIFIER = com.roli.pluginhost;
+                               PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.pluginhost;
                                SDKROOT_ppc = macosx10.5;
                                USE_HEADERMAP = NO; }; name = Release; };
                8D1CA827F1EFD443BDCF198A = {isa = XCBuildConfiguration; buildSettings = {
                                        C8B793AC1BEFBE7A99BE8352,
                                        49453CC5AD9F08D2738464AC, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
                2429BB4D705CC57F49418CFB = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (
-                                       D92C7BF86C9CCF6B4D14F809, ); runOnlyForDeploymentPostprocessing = 0; };
+                                       D92C7BF86C9CCF6B4D14F809,
+                                       443244451A0F2064D4767337, ); runOnlyForDeploymentPostprocessing = 0; };
                E8E94B3C187DA578BFCBDA98 = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (
-                                       4C88899EB7993A76A97643FE,
-                                       485A37478F7EAA352DD1A86A,
-                                       040EB574807E8A86F124D851,
+                                       2E74188531792924F0C73142,
+                                       C8423A9611C8AAF27468847D,
+                                       786AF545C1C1E4D11140C3DF,
+                                       3E1689E23B9C85F03209DCEF,
+                                       F635D974599DEC2ED91E6A88,
                                        A1B0416DA378BB0C3AD6F74B,
-                                       D493393499E0822C70009A63,
-                                       6CD3B433544911DA879170AE,
+                                       A0144A682BF4843C8CF53FE4,
                                        15CCE43D7DCFC649638919D4,
                                        5C4D406B924230F83E3580AD,
                                        F4DD98B9310B679D50A2C8A6,
diff --git a/extras/AudioPluginHost/Builds/MacOSX/Icon.icns b/extras/AudioPluginHost/Builds/MacOSX/Icon.icns
new file mode 100644 (file)
index 0000000..6ab6915
Binary files /dev/null and b/extras/AudioPluginHost/Builds/MacOSX/Icon.icns differ
index 2759638b5e040b80808a779f13bb605b70c5695c..bc0a8928552e6dcaaadf86c88b73d3de83d7f267 100644 (file)
@@ -6,9 +6,9 @@
     <key>CFBundleExecutable</key>\r
     <string>${EXECUTABLE_NAME}</string>\r
     <key>CFBundleIconFile</key>\r
-    <string></string>\r
+    <string>Icon.icns</string>\r
     <key>CFBundleIdentifier</key>\r
-    <string>com.roli.pluginhost</string>\r
+    <string>com.roli.juce.pluginhost</string>\r
     <key>CFBundleName</key>\r
     <string>AudioPluginHost</string>\r
     <key>CFBundleDisplayName</key>\r
index 40d92912f6caf90e52b2a4982c6eb0366e6c80d6..dcc1d5dd8ade4fd1dd47b5c153bdf7db2033c64b 100644 (file)
     <Lib/>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="..\..\Source\FilterGraph.cpp"/>\r
-    <ClCompile Include="..\..\Source\FilterIOConfiguration.cpp"/>\r
-    <ClCompile Include="..\..\Source\GraphEditorPanel.cpp"/>\r
+    <ClCompile Include="..\..\Source\Filters\FilterGraph.cpp"/>\r
+    <ClCompile Include="..\..\Source\Filters\FilterIOConfiguration.cpp"/>\r
+    <ClCompile Include="..\..\Source\Filters\InternalFilters.cpp"/>\r
+    <ClCompile Include="..\..\Source\UI\GraphEditorPanel.cpp"/>\r
+    <ClCompile Include="..\..\Source\UI\MainHostWindow.cpp"/>\r
     <ClCompile Include="..\..\Source\HostStartup.cpp"/>\r
-    <ClCompile Include="..\..\Source\InternalFilters.cpp"/>\r
-    <ClCompile Include="..\..\Source\MainHostWindow.cpp"/>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioChannelSet.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"/>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_basics.cpp"/>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_devices.cpp"/>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_formats.cpp"/>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_video.cpp"/>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClInclude Include="..\..\Source\FilterGraph.h"/>\r
-    <ClInclude Include="..\..\Source\FilterIOConfiguration.h"/>\r
-    <ClInclude Include="..\..\Source\GraphEditorPanel.h"/>\r
-    <ClInclude Include="..\..\Source\InternalFilters.h"/>\r
-    <ClInclude Include="..\..\Source\MainHostWindow.h"/>\r
-    <ClInclude Include="..\..\Source\PluginWindow.h"/>\r
+    <ClInclude Include="..\..\Source\Filters\FilterGraph.h"/>\r
+    <ClInclude Include="..\..\Source\Filters\FilterIOConfiguration.h"/>\r
+    <ClInclude Include="..\..\Source\Filters\InternalFilters.h"/>\r
+    <ClInclude Include="..\..\Source\UI\GraphEditorPanel.h"/>\r
+    <ClInclude Include="..\..\Source\UI\MainHostWindow.h"/>\r
+    <ClInclude Include="..\..\Source\UI\PluginWindow.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_audio_basics\audio_play_head\juce_AudioPlayHead.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioChannelSet.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioDataConverters.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"/>\r
     <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/>\r
+    <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/>\r
     <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/>\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <None Include="..\..\Source\JUCEAppIcon.png"/>\r
     <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"/>\r
     <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"/>\r
     <None Include="..\..\..\..\modules\juce_graphics\image_formats\jpglib\changes to libjpeg for JUCE.txt"/>\r
     <None Include="..\..\..\..\modules\juce_graphics\image_formats\pnglib\libpng_readme.txt"/>\r
+    <None Include=".\icon.ico"/>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include=".\resources.rc"/>\r
index fa835208fd86f447913602f894a4eb24b28e9619..7415956798b038392d7c2ea73b9bfe668a1abd4c 100644 (file)
@@ -2,6 +2,15 @@
 \r
 <Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
   <ItemGroup>\r
+    <Filter Include="AudioPluginHost\Source\Filters">\r
+      <UniqueIdentifier>{01436C03-42F4-5952-30EF-7F9E81D997C6}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="AudioPluginHost\Source\UI">\r
+      <UniqueIdentifier>{8C61EB30-11E6-7029-4CC8-56C52EB1F1C3}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="AudioPluginHost\Source">\r
+      <UniqueIdentifier>{57E59C1B-8971-243F-9A1A-8EABFD456232}</UniqueIdentifier>\r
+    </Filter>\r
     <Filter Include="AudioPluginHost">\r
       <UniqueIdentifier>{297DEAC9-184C-CA1D-D75C-DAA34116691C}</UniqueIdentifier>\r
     </Filter>\r
     </Filter>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="..\..\Source\FilterGraph.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\Filters\FilterGraph.cpp">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\FilterIOConfiguration.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\Filters\FilterIOConfiguration.cpp">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\GraphEditorPanel.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\Filters\InternalFilters.cpp">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\HostStartup.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\UI\GraphEditorPanel.cpp">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\InternalFilters.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\UI\MainHostWindow.cpp">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\MainHostWindow.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\HostStartup.cpp">\r
+      <Filter>AudioPluginHost\Source</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioChannelSet.cpp">\r
       <Filter>JUCE Modules\juce_audio_basics\buffers</Filter>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.mm">\r
       <Filter>JUCE Modules\juce_video</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp">\r
+      <Filter>JUCE Library Code</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_basics.cpp">\r
       <Filter>JUCE Library Code</Filter>\r
     </ClCompile>\r
     </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClInclude Include="..\..\Source\FilterGraph.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\Filters\FilterGraph.h">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\FilterIOConfiguration.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\Filters\FilterIOConfiguration.h">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\GraphEditorPanel.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\Filters\InternalFilters.h">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\InternalFilters.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\UI\GraphEditorPanel.h">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\MainHostWindow.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\UI\MainHostWindow.h">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\PluginWindow.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\UI\PluginWindow.h">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_audio_basics\audio_play_head\juce_AudioPlayHead.h">\r
       <Filter>JUCE Modules\juce_audio_basics\audio_play_head</Filter>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h">\r
       <Filter>JUCE Library Code</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h">\r
+      <Filter>JUCE Library Code</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h">\r
       <Filter>JUCE Library Code</Filter>\r
     </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <None Include="..\..\Source\JUCEAppIcon.png">\r
+      <Filter>AudioPluginHost\Source</Filter>\r
+    </None>\r
     <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt">\r
       <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter>\r
     </None>\r
     <None Include="..\..\..\..\modules\juce_graphics\image_formats\pnglib\libpng_readme.txt">\r
       <Filter>JUCE Modules\juce_graphics\image_formats\pnglib</Filter>\r
     </None>\r
+    <None Include=".\icon.ico">\r
+      <Filter>JUCE Library Code</Filter>\r
+    </None>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include=".\resources.rc">\r
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2013/icon.ico b/extras/AudioPluginHost/Builds/VisualStudio2013/icon.ico
new file mode 100644 (file)
index 0000000..09d32ad
Binary files /dev/null and b/extras/AudioPluginHost/Builds/VisualStudio2013/icon.ico differ
index 26eaf75ddbea8b9975a5814058de50112df128a8..8af2d39631ee073705cfe059b247db741c536b97 100644 (file)
@@ -29,3 +29,6 @@ BEGIN
 END\r
 \r
 #endif\r
+\r
+IDI_ICON1 ICON DISCARDABLE "icon.ico"\r
+IDI_ICON2 ICON DISCARDABLE "icon.ico"
\ No newline at end of file
index f532f4611925769164a080d2a1949fb92dac3035..a27197c849f83b13bba1250435e47c055a324a5f 100644 (file)
     <Lib/>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="..\..\Source\FilterGraph.cpp"/>\r
-    <ClCompile Include="..\..\Source\FilterIOConfiguration.cpp"/>\r
-    <ClCompile Include="..\..\Source\GraphEditorPanel.cpp"/>\r
+    <ClCompile Include="..\..\Source\Filters\FilterGraph.cpp"/>\r
+    <ClCompile Include="..\..\Source\Filters\FilterIOConfiguration.cpp"/>\r
+    <ClCompile Include="..\..\Source\Filters\InternalFilters.cpp"/>\r
+    <ClCompile Include="..\..\Source\UI\GraphEditorPanel.cpp"/>\r
+    <ClCompile Include="..\..\Source\UI\MainHostWindow.cpp"/>\r
     <ClCompile Include="..\..\Source\HostStartup.cpp"/>\r
-    <ClCompile Include="..\..\Source\InternalFilters.cpp"/>\r
-    <ClCompile Include="..\..\Source\MainHostWindow.cpp"/>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioChannelSet.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"/>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_basics.cpp"/>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_devices.cpp"/>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_formats.cpp"/>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_video.cpp"/>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClInclude Include="..\..\Source\FilterGraph.h"/>\r
-    <ClInclude Include="..\..\Source\FilterIOConfiguration.h"/>\r
-    <ClInclude Include="..\..\Source\GraphEditorPanel.h"/>\r
-    <ClInclude Include="..\..\Source\InternalFilters.h"/>\r
-    <ClInclude Include="..\..\Source\MainHostWindow.h"/>\r
-    <ClInclude Include="..\..\Source\PluginWindow.h"/>\r
+    <ClInclude Include="..\..\Source\Filters\FilterGraph.h"/>\r
+    <ClInclude Include="..\..\Source\Filters\FilterIOConfiguration.h"/>\r
+    <ClInclude Include="..\..\Source\Filters\InternalFilters.h"/>\r
+    <ClInclude Include="..\..\Source\UI\GraphEditorPanel.h"/>\r
+    <ClInclude Include="..\..\Source\UI\MainHostWindow.h"/>\r
+    <ClInclude Include="..\..\Source\UI\PluginWindow.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_audio_basics\audio_play_head\juce_AudioPlayHead.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioChannelSet.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioDataConverters.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"/>\r
     <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/>\r
+    <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/>\r
     <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/>\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <None Include="..\..\Source\JUCEAppIcon.png"/>\r
     <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"/>\r
     <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"/>\r
     <None Include="..\..\..\..\modules\juce_graphics\image_formats\jpglib\changes to libjpeg for JUCE.txt"/>\r
     <None Include="..\..\..\..\modules\juce_graphics\image_formats\pnglib\libpng_readme.txt"/>\r
+    <None Include=".\icon.ico"/>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include=".\resources.rc"/>\r
index ba4ce19d295345d24db35e8dbba0de1fd29496b8..87f7846b1ae5a96aed03606f9bdfd2756990cf29 100644 (file)
@@ -2,6 +2,15 @@
 \r
 <Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
   <ItemGroup>\r
+    <Filter Include="AudioPluginHost\Source\Filters">\r
+      <UniqueIdentifier>{01436C03-42F4-5952-30EF-7F9E81D997C6}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="AudioPluginHost\Source\UI">\r
+      <UniqueIdentifier>{8C61EB30-11E6-7029-4CC8-56C52EB1F1C3}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="AudioPluginHost\Source">\r
+      <UniqueIdentifier>{57E59C1B-8971-243F-9A1A-8EABFD456232}</UniqueIdentifier>\r
+    </Filter>\r
     <Filter Include="AudioPluginHost">\r
       <UniqueIdentifier>{297DEAC9-184C-CA1D-D75C-DAA34116691C}</UniqueIdentifier>\r
     </Filter>\r
     </Filter>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="..\..\Source\FilterGraph.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\Filters\FilterGraph.cpp">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\FilterIOConfiguration.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\Filters\FilterIOConfiguration.cpp">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\GraphEditorPanel.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\Filters\InternalFilters.cpp">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\HostStartup.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\UI\GraphEditorPanel.cpp">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\InternalFilters.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\UI\MainHostWindow.cpp">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\MainHostWindow.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\HostStartup.cpp">\r
+      <Filter>AudioPluginHost\Source</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioChannelSet.cpp">\r
       <Filter>JUCE Modules\juce_audio_basics\buffers</Filter>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.mm">\r
       <Filter>JUCE Modules\juce_video</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp">\r
+      <Filter>JUCE Library Code</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_basics.cpp">\r
       <Filter>JUCE Library Code</Filter>\r
     </ClCompile>\r
     </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClInclude Include="..\..\Source\FilterGraph.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\Filters\FilterGraph.h">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\FilterIOConfiguration.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\Filters\FilterIOConfiguration.h">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\GraphEditorPanel.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\Filters\InternalFilters.h">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\InternalFilters.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\UI\GraphEditorPanel.h">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\MainHostWindow.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\UI\MainHostWindow.h">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\PluginWindow.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\UI\PluginWindow.h">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_audio_basics\audio_play_head\juce_AudioPlayHead.h">\r
       <Filter>JUCE Modules\juce_audio_basics\audio_play_head</Filter>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h">\r
       <Filter>JUCE Library Code</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h">\r
+      <Filter>JUCE Library Code</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h">\r
       <Filter>JUCE Library Code</Filter>\r
     </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <None Include="..\..\Source\JUCEAppIcon.png">\r
+      <Filter>AudioPluginHost\Source</Filter>\r
+    </None>\r
     <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt">\r
       <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter>\r
     </None>\r
     <None Include="..\..\..\..\modules\juce_graphics\image_formats\pnglib\libpng_readme.txt">\r
       <Filter>JUCE Modules\juce_graphics\image_formats\pnglib</Filter>\r
     </None>\r
+    <None Include=".\icon.ico">\r
+      <Filter>JUCE Library Code</Filter>\r
+    </None>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include=".\resources.rc">\r
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2015/icon.ico b/extras/AudioPluginHost/Builds/VisualStudio2015/icon.ico
new file mode 100644 (file)
index 0000000..09d32ad
Binary files /dev/null and b/extras/AudioPluginHost/Builds/VisualStudio2015/icon.ico differ
index 26eaf75ddbea8b9975a5814058de50112df128a8..8af2d39631ee073705cfe059b247db741c536b97 100644 (file)
@@ -29,3 +29,6 @@ BEGIN
 END\r
 \r
 #endif\r
+\r
+IDI_ICON1 ICON DISCARDABLE "icon.ico"\r
+IDI_ICON2 ICON DISCARDABLE "icon.ico"
\ No newline at end of file
index acdf760a33907b58bb5b68e01dc61e71ba8b851d..989607160f59eaa28238b1c9368bb212e0fcca34 100644 (file)
     <Lib/>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="..\..\Source\FilterGraph.cpp"/>\r
-    <ClCompile Include="..\..\Source\FilterIOConfiguration.cpp"/>\r
-    <ClCompile Include="..\..\Source\GraphEditorPanel.cpp"/>\r
+    <ClCompile Include="..\..\Source\Filters\FilterGraph.cpp"/>\r
+    <ClCompile Include="..\..\Source\Filters\FilterIOConfiguration.cpp"/>\r
+    <ClCompile Include="..\..\Source\Filters\InternalFilters.cpp"/>\r
+    <ClCompile Include="..\..\Source\UI\GraphEditorPanel.cpp"/>\r
+    <ClCompile Include="..\..\Source\UI\MainHostWindow.cpp"/>\r
     <ClCompile Include="..\..\Source\HostStartup.cpp"/>\r
-    <ClCompile Include="..\..\Source\InternalFilters.cpp"/>\r
-    <ClCompile Include="..\..\Source\MainHostWindow.cpp"/>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioChannelSet.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"/>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_basics.cpp"/>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_devices.cpp"/>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_formats.cpp"/>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_video.cpp"/>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClInclude Include="..\..\Source\FilterGraph.h"/>\r
-    <ClInclude Include="..\..\Source\FilterIOConfiguration.h"/>\r
-    <ClInclude Include="..\..\Source\GraphEditorPanel.h"/>\r
-    <ClInclude Include="..\..\Source\InternalFilters.h"/>\r
-    <ClInclude Include="..\..\Source\MainHostWindow.h"/>\r
-    <ClInclude Include="..\..\Source\PluginWindow.h"/>\r
+    <ClInclude Include="..\..\Source\Filters\FilterGraph.h"/>\r
+    <ClInclude Include="..\..\Source\Filters\FilterIOConfiguration.h"/>\r
+    <ClInclude Include="..\..\Source\Filters\InternalFilters.h"/>\r
+    <ClInclude Include="..\..\Source\UI\GraphEditorPanel.h"/>\r
+    <ClInclude Include="..\..\Source\UI\MainHostWindow.h"/>\r
+    <ClInclude Include="..\..\Source\UI\PluginWindow.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_audio_basics\audio_play_head\juce_AudioPlayHead.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioChannelSet.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioDataConverters.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"/>\r
     <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/>\r
+    <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/>\r
     <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/>\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <None Include="..\..\Source\JUCEAppIcon.png"/>\r
     <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"/>\r
     <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"/>\r
     <None Include="..\..\..\..\modules\juce_graphics\image_formats\jpglib\changes to libjpeg for JUCE.txt"/>\r
     <None Include="..\..\..\..\modules\juce_graphics\image_formats\pnglib\libpng_readme.txt"/>\r
+    <None Include=".\icon.ico"/>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include=".\resources.rc"/>\r
index fb87f14052c598536eddc2410c43044abe4b4f5c..87a6356e2ba153775e17054ef06450d10d265016 100644 (file)
@@ -2,6 +2,15 @@
 \r
 <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
   <ItemGroup>\r
+    <Filter Include="AudioPluginHost\Source\Filters">\r
+      <UniqueIdentifier>{01436C03-42F4-5952-30EF-7F9E81D997C6}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="AudioPluginHost\Source\UI">\r
+      <UniqueIdentifier>{8C61EB30-11E6-7029-4CC8-56C52EB1F1C3}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="AudioPluginHost\Source">\r
+      <UniqueIdentifier>{57E59C1B-8971-243F-9A1A-8EABFD456232}</UniqueIdentifier>\r
+    </Filter>\r
     <Filter Include="AudioPluginHost">\r
       <UniqueIdentifier>{297DEAC9-184C-CA1D-D75C-DAA34116691C}</UniqueIdentifier>\r
     </Filter>\r
     </Filter>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="..\..\Source\FilterGraph.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\Filters\FilterGraph.cpp">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\FilterIOConfiguration.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\Filters\FilterIOConfiguration.cpp">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\GraphEditorPanel.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\Filters\InternalFilters.cpp">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\HostStartup.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\UI\GraphEditorPanel.cpp">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\InternalFilters.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\UI\MainHostWindow.cpp">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\..\Source\MainHostWindow.cpp">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClCompile Include="..\..\Source\HostStartup.cpp">\r
+      <Filter>AudioPluginHost\Source</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioChannelSet.cpp">\r
       <Filter>JUCE Modules\juce_audio_basics\buffers</Filter>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.mm">\r
       <Filter>JUCE Modules\juce_video</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp">\r
+      <Filter>JUCE Library Code</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_basics.cpp">\r
       <Filter>JUCE Library Code</Filter>\r
     </ClCompile>\r
     </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClInclude Include="..\..\Source\FilterGraph.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\Filters\FilterGraph.h">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\FilterIOConfiguration.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\Filters\FilterIOConfiguration.h">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\GraphEditorPanel.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\Filters\InternalFilters.h">\r
+      <Filter>AudioPluginHost\Source\Filters</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\InternalFilters.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\UI\GraphEditorPanel.h">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\MainHostWindow.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\UI\MainHostWindow.h">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\..\Source\PluginWindow.h">\r
-      <Filter>AudioPluginHost</Filter>\r
+    <ClInclude Include="..\..\Source\UI\PluginWindow.h">\r
+      <Filter>AudioPluginHost\Source\UI</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_audio_basics\audio_play_head\juce_AudioPlayHead.h">\r
       <Filter>JUCE Modules\juce_audio_basics\audio_play_head</Filter>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h">\r
       <Filter>JUCE Library Code</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h">\r
+      <Filter>JUCE Library Code</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h">\r
       <Filter>JUCE Library Code</Filter>\r
     </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <None Include="..\..\Source\JUCEAppIcon.png">\r
+      <Filter>AudioPluginHost\Source</Filter>\r
+    </None>\r
     <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt">\r
       <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter>\r
     </None>\r
     <None Include="..\..\..\..\modules\juce_graphics\image_formats\pnglib\libpng_readme.txt">\r
       <Filter>JUCE Modules\juce_graphics\image_formats\pnglib</Filter>\r
     </None>\r
+    <None Include=".\icon.ico">\r
+      <Filter>JUCE Library Code</Filter>\r
+    </None>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include=".\resources.rc">\r
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/icon.ico b/extras/AudioPluginHost/Builds/VisualStudio2017/icon.ico
new file mode 100644 (file)
index 0000000..09d32ad
Binary files /dev/null and b/extras/AudioPluginHost/Builds/VisualStudio2017/icon.ico differ
index 26eaf75ddbea8b9975a5814058de50112df128a8..8af2d39631ee073705cfe059b247db741c536b97 100644 (file)
@@ -29,3 +29,6 @@ BEGIN
 END\r
 \r
 #endif\r
+\r
+IDI_ICON1 ICON DISCARDABLE "icon.ico"\r
+IDI_ICON2 ICON DISCARDABLE "icon.ico"
\ No newline at end of file
diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..ddd00de
--- /dev/null
@@ -0,0 +1,398 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 46;
+       objects = {
+
+               FCDB1F8A93F59E0F97821456 = {isa = PBXBuildFile; fileRef = 8D8BBC353637DA442C5575DA; };
+               73E371F1B912FCCAE0CD7E5D = {isa = PBXBuildFile; fileRef = 86CA337014D3F67E906FFD28; };
+               21D330A5B13178B12BEAFC3C = {isa = PBXBuildFile; fileRef = D4EBC17BDB7F88CCBC76730B; };
+               851C1165C9E4ACDD19C56A96 = {isa = PBXBuildFile; fileRef = 942A0F04EFB8D0B2FF9780BA; };
+               AF42316D915057E930A5624E = {isa = PBXBuildFile; fileRef = A4B568E26157FC282214976F; };
+               E3CB85BA817BC9E3942A8AB0 = {isa = PBXBuildFile; fileRef = 9F9B445E6755CAA19E4344ED; };
+               70580743C3D5695F065FF698 = {isa = PBXBuildFile; fileRef = E68018DE199135B7F738FB17; };
+               1570FCC5CDB7A44DF0077E39 = {isa = PBXBuildFile; fileRef = 2F7D965A1284CEF0B20EB657; };
+               B0D5475F716126465FCE1586 = {isa = PBXBuildFile; fileRef = CFFA8E9A7820C5A27B4393C9; };
+               3470F40DA5D68EC217872906 = {isa = PBXBuildFile; fileRef = 31D55A751C790CB81F58DDB7; };
+               E092A70431B046BF1F50A482 = {isa = PBXBuildFile; fileRef = 5AF0CA7CDFCA90B4DE1F55C3; };
+               92EE84159C7027A137F06204 = {isa = PBXBuildFile; fileRef = 66643EDF46AE8C5B7956B91D; };
+               9056B642BEF870098DE344E5 = {isa = PBXBuildFile; fileRef = 03FA420AACDD03D50AA16E4A; };
+               7DE81C004B0FBC563040CC5F = {isa = PBXBuildFile; fileRef = B1CD9599EB12D77E8AF9241D; };
+               2AB9A26C9359C40CA0A937ED = {isa = PBXBuildFile; fileRef = D0026F0A29B486D87E92BB8B; };
+               A02C9F4C4B840C27B6CAFEBD = {isa = PBXBuildFile; fileRef = 89309C0C5F3269BD06BE7F27; };
+               50AFD116DCA6EC228EFB322D = {isa = PBXBuildFile; fileRef = F9EDC54DFBCF3A63E0AA5D73; };
+               59F4F23BFFDAB414B4801F85 = {isa = PBXBuildFile; fileRef = 29E0972229FB44D969035B4E; };
+               443244451A0F2064D4767337 = {isa = PBXBuildFile; fileRef = 2A6983F82B13F9E8B10299AE; };
+               2E74188531792924F0C73142 = {isa = PBXBuildFile; fileRef = 05863BDFC582C9552A86DF49; };
+               C8423A9611C8AAF27468847D = {isa = PBXBuildFile; fileRef = 336FD30C38BD0A176161B8AE; };
+               786AF545C1C1E4D11140C3DF = {isa = PBXBuildFile; fileRef = 43647951ECC7F030B9953965; };
+               3E1689E23B9C85F03209DCEF = {isa = PBXBuildFile; fileRef = 3D78A731234A833CA112AE45; };
+               F635D974599DEC2ED91E6A88 = {isa = PBXBuildFile; fileRef = 04AABCD3491318FB32E844B4; };
+               A1B0416DA378BB0C3AD6F74B = {isa = PBXBuildFile; fileRef = A66EFAC64B1B67B536C73415; };
+               A0144A682BF4843C8CF53FE4 = {isa = PBXBuildFile; fileRef = 6D107D7946DC5976B766345B; };
+               15CCE43D7DCFC649638919D4 = {isa = PBXBuildFile; fileRef = 4C7D82F9274A4F9DBF11235C; };
+               5C4D406B924230F83E3580AD = {isa = PBXBuildFile; fileRef = 65968EA1B476D71F14DE1D58; };
+               F4DD98B9310B679D50A2C8A6 = {isa = PBXBuildFile; fileRef = 5D250A57C7DEA80248F30EED; };
+               CAF0DE157C8F7D9F168AA3B6 = {isa = PBXBuildFile; fileRef = 5FBD6C402617272052BB4D81; };
+               0F20A4AE04736634F097F5A6 = {isa = PBXBuildFile; fileRef = B285CAB91AE928C476CA4F9C; };
+               76A80851698FC773D2479B4E = {isa = PBXBuildFile; fileRef = 683CEE986A2467C850FE99E6; };
+               E4A926EF695823F0F13268FF = {isa = PBXBuildFile; fileRef = B8E24A5CEE6B7055537725CF; };
+               A09E93F1B354E1FF8B3E9ABE = {isa = PBXBuildFile; fileRef = 5EF1D381F42AA8764597F189; };
+               7DE202DC1D876F49266D9E7D = {isa = PBXBuildFile; fileRef = 8290D7BAC160B3A56B66891A; };
+               075C54DDDBDEA5AAD2F60154 = {isa = PBXBuildFile; fileRef = 82800DBA287EF4BAB13B42FB; };
+               2C3D221D2AA87F07B3F1044D = {isa = PBXBuildFile; fileRef = 8FE7B37CDE0818DB27BDDEBD; };
+               C38D14DC58F1941DD5E4BF60 = {isa = PBXBuildFile; fileRef = 2BE6C2DFD6EBB9A89109AEB5; };
+               2727A191DB1BAAC9C04B9081 = {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; lastKnownFileType = sourcecode.cpp.cpp; name = MainHostWindow.cpp; path = ../../Source/UI/MainHostWindow.cpp; sourceTree = "SOURCE_ROOT"; };
+               04DB9A49969ECC740CC25665 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GraphEditorPanel.h; path = ../../Source/UI/GraphEditorPanel.h; sourceTree = "SOURCE_ROOT"; };
+               05863BDFC582C9552A86DF49 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FilterGraph.cpp; path = ../../Source/Filters/FilterGraph.cpp; sourceTree = "SOURCE_ROOT"; };
+               1DADAD8E34AAF4AFF1C69DC4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BinaryData.h; 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; name = Images.xcassets; path = AudioPluginHost/Images.xcassets; sourceTree = "SOURCE_ROOT"; };
+               2A6983F82B13F9E8B10299AE = {isa = PBXFileReference; lastKnownFileType = file.icns; name = Icon.icns; path = Icon.icns; sourceTree = "SOURCE_ROOT"; };
+               2BE6C2DFD6EBB9A89109AEB5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_extra.mm"; path = "../../JuceLibraryCode/include_juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; };
+               2F7D965A1284CEF0B20EB657 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+               30F22843EFEBF7AA841EB4D6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; };
+               31D55A751C790CB81F58DDB7 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
+               336FD30C38BD0A176161B8AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FilterIOConfiguration.cpp; path = ../../Source/Filters/FilterIOConfiguration.cpp; sourceTree = "SOURCE_ROOT"; };
+               37E4D5C341406B7072120006 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_opengl.mm"; path = "../../JuceLibraryCode/include_juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; };
+               3C070DD522CDD11FFC87425D = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_utils"; path = "../../../../modules/juce_audio_utils"; sourceTree = "SOURCE_ROOT"; };
+               3D57FE2A8877F12A61054726 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_core"; path = "../../../../modules/juce_core"; sourceTree = "SOURCE_ROOT"; };
+               3D78A731234A833CA112AE45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = GraphEditorPanel.cpp; path = ../../Source/UI/GraphEditorPanel.cpp; sourceTree = "SOURCE_ROOT"; };
+               43647951ECC7F030B9953965 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = InternalFilters.cpp; path = ../../Source/Filters/InternalFilters.cpp; sourceTree = "SOURCE_ROOT"; };
+               4C7D82F9274A4F9DBF11235C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_basics.mm"; path = "../../JuceLibraryCode/include_juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; };
+               5313EB852E41EE58B199B9A2 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_devices"; path = "../../../../modules/juce_audio_devices"; sourceTree = "SOURCE_ROOT"; };
+               545D57A6AA801B38548B0CAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FilterGraph.h; path = ../../Source/Filters/FilterGraph.h; sourceTree = "SOURCE_ROOT"; };
+               57DF618F1DE781556B7AFC32 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-App.plist"; path = "Info-App.plist"; sourceTree = "SOURCE_ROOT"; };
+               59842A98E5EBBC54B50C04CD = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_events"; path = "../../../../modules/juce_events"; sourceTree = "SOURCE_ROOT"; };
+               5AF0CA7CDFCA90B4DE1F55C3 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
+               5D250A57C7DEA80248F30EED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_formats.mm"; path = "../../JuceLibraryCode/include_juce_audio_formats.mm"; sourceTree = "SOURCE_ROOT"; };
+               5EF1D381F42AA8764597F189 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_data_structures.mm"; path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
+               5FBD6C402617272052BB4D81 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_processors.mm"; path = "../../JuceLibraryCode/include_juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; };
+               65968EA1B476D71F14DE1D58 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_devices.mm"; path = "../../JuceLibraryCode/include_juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; };
+               66643EDF46AE8C5B7956B91D = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
+               683CEE986A2467C850FE99E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_core.mm"; path = "../../JuceLibraryCode/include_juce_core.mm"; sourceTree = "SOURCE_ROOT"; };
+               6A71B2BCAC4239072BC2BD7E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_basics"; path = "../../../../modules/juce_audio_basics"; sourceTree = "SOURCE_ROOT"; };
+               6D107D7946DC5976B766345B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = BinaryData.cpp; path = ../../JuceLibraryCode/BinaryData.cpp; sourceTree = "SOURCE_ROOT"; };
+               725D0D9C8C7FF7B3FB3020ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FilterIOConfiguration.h; path = ../../Source/Filters/FilterIOConfiguration.h; sourceTree = "SOURCE_ROOT"; };
+               81C1A7770E082F56FE5A90A7 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_opengl"; path = "../../../../modules/juce_opengl"; sourceTree = "SOURCE_ROOT"; };
+               82800DBA287EF4BAB13B42FB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_graphics.mm"; path = "../../JuceLibraryCode/include_juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; };
+               8290D7BAC160B3A56B66891A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_events.mm"; path = "../../JuceLibraryCode/include_juce_events.mm"; sourceTree = "SOURCE_ROOT"; };
+               86CA337014D3F67E906FFD28 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
+               89309C0C5F3269BD06BE7F27 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+               8D8BBC353637DA442C5575DA = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Plugin Host.app"; sourceTree = "BUILT_PRODUCTS_DIR"; };
+               8FE7B37CDE0818DB27BDDEBD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_basics.mm"; path = "../../JuceLibraryCode/include_juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; };
+               938AE72315C6C93949F6220E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_basics"; 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; name = "juce_graphics"; path = "../../../../modules/juce_graphics"; sourceTree = "SOURCE_ROOT"; };
+               97918AB43AD460AFA8FA2FFE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PluginWindow.h; path = ../../Source/UI/PluginWindow.h; sourceTree = "SOURCE_ROOT"; };
+               9EBEE3AE5856E877478607C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InternalFilters.h; path = ../../Source/Filters/InternalFilters.h; sourceTree = "SOURCE_ROOT"; };
+               9F9B445E6755CAA19E4344ED = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; 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; name = MainHostWindow.h; path = ../../Source/UI/MainHostWindow.h; sourceTree = "SOURCE_ROOT"; };
+               A5E7CA8A71D049BE2BD33861 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; };
+               A66EFAC64B1B67B536C73415 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = HostStartup.cpp; 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; name = "include_juce_audio_utils.mm"; path = "../../JuceLibraryCode/include_juce_audio_utils.mm"; sourceTree = "SOURCE_ROOT"; };
+               B2A1E626CC120982805754F6 = {isa = PBXFileReference; lastKnownFileType = image.png; name = JUCEAppIcon.png; path = ../../Source/JUCEAppIcon.png; sourceTree = "SOURCE_ROOT"; };
+               B86B918291E1090C6A720971 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_data_structures"; path = "../../../../modules/juce_data_structures"; sourceTree = "SOURCE_ROOT"; };
+               B8E24A5CEE6B7055537725CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_cryptography.mm"; path = "../../JuceLibraryCode/include_juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; };
+               CFFA8E9A7820C5A27B4393C9 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; };
+               D0026F0A29B486D87E92BB8B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
+               D4EBC17BDB7F88CCBC76730B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; 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; name = CoreAudioKit.framework; path = System/Library/Frameworks/CoreAudioKit.framework; sourceTree = SDKROOT; };
+               F299BECFB2AEA6105F014848 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_extra"; path = "../../../../modules/juce_gui_extra"; sourceTree = "SOURCE_ROOT"; };
+               F9AC862E9A3583B6C1488EE0 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_formats"; path = "../../../../modules/juce_audio_formats"; sourceTree = "SOURCE_ROOT"; };
+               F9EDC54DFBCF3A63E0AA5D73 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+               FA21631C5536EA3DF55C7FA6 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_cryptography"; path = "../../../../modules/juce_cryptography"; sourceTree = "SOURCE_ROOT"; };
+               FAF867E9E731D0880D40511F = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_processors"; path = "../../../../modules/juce_audio_processors"; sourceTree = "SOURCE_ROOT"; };
+               AA37F82D57C9BB4BE78FCCB9 = {isa = PBXGroup; children = (
+                                       05863BDFC582C9552A86DF49,
+                                       545D57A6AA801B38548B0CAC,
+                                       336FD30C38BD0A176161B8AE,
+                                       725D0D9C8C7FF7B3FB3020ED,
+                                       43647951ECC7F030B9953965,
+                                       9EBEE3AE5856E877478607C7, ); name = Filters; sourceTree = "<group>"; };
+               DE7B77306553B1204071B39A = {isa = PBXGroup; children = (
+                                       3D78A731234A833CA112AE45,
+                                       04DB9A49969ECC740CC25665,
+                                       04AABCD3491318FB32E844B4,
+                                       A5DFC13E4F09134B0D226A3E,
+                                       97918AB43AD460AFA8FA2FFE, ); name = UI; sourceTree = "<group>"; };
+               B225B7F2CAABD28A41E7C339 = {isa = PBXGroup; children = (
+                                       AA37F82D57C9BB4BE78FCCB9,
+                                       DE7B77306553B1204071B39A,
+                                       A66EFAC64B1B67B536C73415,
+                                       B2A1E626CC120982805754F6, ); name = Source; sourceTree = "<group>"; };
+               97790EAEA01CFA5C3CA9737A = {isa = PBXGroup; children = (
+                                       B225B7F2CAABD28A41E7C339, ); name = AudioPluginHost; sourceTree = "<group>"; };
+               9D8FE1F65CAD416AA606C47A = {isa = PBXGroup; children = (
+                                       6A71B2BCAC4239072BC2BD7E,
+                                       5313EB852E41EE58B199B9A2,
+                                       F9AC862E9A3583B6C1488EE0,
+                                       FAF867E9E731D0880D40511F,
+                                       3C070DD522CDD11FFC87425D,
+                                       3D57FE2A8877F12A61054726,
+                                       FA21631C5536EA3DF55C7FA6,
+                                       B86B918291E1090C6A720971,
+                                       59842A98E5EBBC54B50C04CD,
+                                       94CB96C8E4B51F52776C2638,
+                                       938AE72315C6C93949F6220E,
+                                       F299BECFB2AEA6105F014848,
+                                       81C1A7770E082F56FE5A90A7,
+                                       DDE115D3084ACA6DD6AA4471, ); name = "JUCE Modules"; sourceTree = "<group>"; };
+               7E30376DDAD775FEFE64944C = {isa = PBXGroup; children = (
+                                       30F22843EFEBF7AA841EB4D6,
+                                       6D107D7946DC5976B766345B,
+                                       1DADAD8E34AAF4AFF1C69DC4,
+                                       4C7D82F9274A4F9DBF11235C,
+                                       65968EA1B476D71F14DE1D58,
+                                       5D250A57C7DEA80248F30EED,
+                                       5FBD6C402617272052BB4D81,
+                                       B285CAB91AE928C476CA4F9C,
+                                       683CEE986A2467C850FE99E6,
+                                       B8E24A5CEE6B7055537725CF,
+                                       5EF1D381F42AA8764597F189,
+                                       8290D7BAC160B3A56B66891A,
+                                       82800DBA287EF4BAB13B42FB,
+                                       8FE7B37CDE0818DB27BDDEBD,
+                                       2BE6C2DFD6EBB9A89109AEB5,
+                                       37E4D5C341406B7072120006,
+                                       29D746FC68F69751796671A2,
+                                       A5E7CA8A71D049BE2BD33861, ); name = "JUCE Library Code"; sourceTree = "<group>"; };
+               A97EE73C79DA3F729D46AF48 = {isa = PBXGroup; children = (
+                                       57DF618F1DE781556B7AFC32,
+                                       29E0972229FB44D969035B4E,
+                                       2A6983F82B13F9E8B10299AE, ); name = Resources; sourceTree = "<group>"; };
+               D1C4804CD275CB57A5C89A2D = {isa = PBXGroup; children = (
+                                       86CA337014D3F67E906FFD28,
+                                       D4EBC17BDB7F88CCBC76730B,
+                                       942A0F04EFB8D0B2FF9780BA,
+                                       A4B568E26157FC282214976F,
+                                       9F9B445E6755CAA19E4344ED,
+                                       E68018DE199135B7F738FB17,
+                                       2F7D965A1284CEF0B20EB657,
+                                       CFFA8E9A7820C5A27B4393C9,
+                                       31D55A751C790CB81F58DDB7,
+                                       5AF0CA7CDFCA90B4DE1F55C3,
+                                       66643EDF46AE8C5B7956B91D,
+                                       03FA420AACDD03D50AA16E4A,
+                                       B1CD9599EB12D77E8AF9241D,
+                                       D0026F0A29B486D87E92BB8B,
+                                       89309C0C5F3269BD06BE7F27,
+                                       F9EDC54DFBCF3A63E0AA5D73, ); name = Frameworks; sourceTree = "<group>"; };
+               D85C0D11EE4F6C73B9EB5BCD = {isa = PBXGroup; children = (
+                                       8D8BBC353637DA442C5575DA, ); name = Products; sourceTree = "<group>"; };
+               65BEFC705A89E5C8A9E35C97 = {isa = PBXGroup; children = (
+                                       97790EAEA01CFA5C3CA9737A,
+                                       9D8FE1F65CAD416AA606C47A,
+                                       7E30376DDAD775FEFE64944C,
+                                       A97EE73C79DA3F729D46AF48,
+                                       D1C4804CD275CB57A5C89A2D,
+                                       D85C0D11EE4F6C73B9EB5BCD, ); name = Source; sourceTree = "<group>"; };
+               C8B793AC1BEFBE7A99BE8352 = {isa = XCBuildConfiguration; buildSettings = {
+                               ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+                               ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
+                               CLANG_CXX_LANGUAGE_STANDARD = "c++14";
+                               CLANG_LINK_OBJC_RUNTIME = NO;
+                               COMBINE_HIDPI_IMAGES = YES;
+                               CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
+                               COPY_PHASE_STRIP = NO;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "_DEBUG=1",
+                                       "DEBUG=1",
+                                       "JUCER_XCODE_IPHONE_5BC26AE3=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", );
+                               GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+                               HEADER_SEARCH_PATHS = ("~/SDKs/VST_SDK/VST3_SDK", "../../JuceLibraryCode", "../../../../modules", "$(inherited)");
+                               INFOPLIST_FILE = Info-App.plist;
+                               INFOPLIST_PREPROCESS = NO;
+                               INSTALL_PATH = "$(HOME)/Applications";
+                               PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.pluginhost;
+                               USE_HEADERMAP = NO; }; name = Debug; };
+               49453CC5AD9F08D2738464AC = {isa = XCBuildConfiguration; buildSettings = {
+                               ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+                               ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
+                               CLANG_CXX_LANGUAGE_STANDARD = "c++14";
+                               CLANG_LINK_OBJC_RUNTIME = NO;
+                               COMBINE_HIDPI_IMAGES = YES;
+                               CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
+                               DEAD_CODE_STRIPPING = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_OPTIMIZATION_LEVEL = 3;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "_NDEBUG=1",
+                                       "NDEBUG=1",
+                                       "JUCER_XCODE_IPHONE_5BC26AE3=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", );
+                               GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+                               GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+                               HEADER_SEARCH_PATHS = ("~/SDKs/VST_SDK/VST3_SDK", "../../JuceLibraryCode", "../../../../modules", "$(inherited)");
+                               INFOPLIST_FILE = Info-App.plist;
+                               INFOPLIST_PREPROCESS = NO;
+                               INSTALL_PATH = "$(HOME)/Applications";
+                               LLVM_LTO = YES;
+                               PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.pluginhost;
+                               USE_HEADERMAP = NO; }; name = Release; };
+               8D1CA827F1EFD443BDCF198A = {isa = XCBuildConfiguration; buildSettings = {
+                               "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_COMMA = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+                               CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+                               CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+                               CLANG_WARN_STRICT_PROTOTYPES = YES;
+                               CLANG_WARN_SUSPICIOUS_MOVE = YES;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf";
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               ENABLE_TESTABILITY = YES;
+                               GCC_C_LANGUAGE_STANDARD = c11;
+                               GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_NO_COMMON_BLOCKS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
+                               GCC_WARN_MISSING_PARENTHESES = YES;
+                               GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
+                               GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+                               ONLY_ACTIVE_ARCH = YES;
+                               PRODUCT_NAME = "Plugin Host";
+                               SDKROOT = iphoneos;
+                               TARGETED_DEVICE_FAMILY = "1,2";
+                               WARNING_CFLAGS = -Wreorder;
+                               ZERO_LINK = NO; }; name = Debug; };
+               C9295196717FABE454A210B7 = {isa = XCBuildConfiguration; buildSettings = {
+                               "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_COMMA = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+                               CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+                               CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+                               CLANG_WARN_STRICT_PROTOTYPES = YES;
+                               CLANG_WARN_SUSPICIOUS_MOVE = YES;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf";
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               GCC_C_LANGUAGE_STANDARD = c11;
+                               GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_NO_COMMON_BLOCKS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
+                               GCC_WARN_MISSING_PARENTHESES = YES;
+                               GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
+                               GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+                               PRODUCT_NAME = "Plugin Host";
+                               SDKROOT = iphoneos;
+                               TARGETED_DEVICE_FAMILY = "1,2";
+                               WARNING_CFLAGS = -Wreorder;
+                               ZERO_LINK = NO; }; name = Release; };
+               B9D79D85AC7DE5BED1B6547C = {isa = PBXTargetDependency; target = DE12B7643D374BFF7E4FEB1C; };
+               493C2C5E457692E5149C5525 = {isa = XCConfigurationList; buildConfigurations = (
+                                       8D1CA827F1EFD443BDCF198A,
+                                       C9295196717FABE454A210B7, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
+               E4ECAE24A646A7D1585F776C = {isa = XCConfigurationList; buildConfigurations = (
+                                       C8B793AC1BEFBE7A99BE8352,
+                                       49453CC5AD9F08D2738464AC, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
+               2429BB4D705CC57F49418CFB = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (
+                                       59F4F23BFFDAB414B4801F85,
+                                       443244451A0F2064D4767337, ); runOnlyForDeploymentPostprocessing = 0; };
+               E8E94B3C187DA578BFCBDA98 = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (
+                                       2E74188531792924F0C73142,
+                                       C8423A9611C8AAF27468847D,
+                                       786AF545C1C1E4D11140C3DF,
+                                       3E1689E23B9C85F03209DCEF,
+                                       F635D974599DEC2ED91E6A88,
+                                       A1B0416DA378BB0C3AD6F74B,
+                                       A0144A682BF4843C8CF53FE4,
+                                       15CCE43D7DCFC649638919D4,
+                                       5C4D406B924230F83E3580AD,
+                                       F4DD98B9310B679D50A2C8A6,
+                                       CAF0DE157C8F7D9F168AA3B6,
+                                       0F20A4AE04736634F097F5A6,
+                                       76A80851698FC773D2479B4E,
+                                       E4A926EF695823F0F13268FF,
+                                       A09E93F1B354E1FF8B3E9ABE,
+                                       7DE202DC1D876F49266D9E7D,
+                                       075C54DDDBDEA5AAD2F60154,
+                                       2C3D221D2AA87F07B3F1044D,
+                                       C38D14DC58F1941DD5E4BF60,
+                                       2727A191DB1BAAC9C04B9081,
+                                       84BAFE82A102D9C350672689, ); runOnlyForDeploymentPostprocessing = 0; };
+               C515A1FE1A53D3968C22FAEF = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (
+                                       73E371F1B912FCCAE0CD7E5D,
+                                       21D330A5B13178B12BEAFC3C,
+                                       851C1165C9E4ACDD19C56A96,
+                                       AF42316D915057E930A5624E,
+                                       E3CB85BA817BC9E3942A8AB0,
+                                       70580743C3D5695F065FF698,
+                                       1570FCC5CDB7A44DF0077E39,
+                                       B0D5475F716126465FCE1586,
+                                       3470F40DA5D68EC217872906,
+                                       E092A70431B046BF1F50A482,
+                                       92EE84159C7027A137F06204,
+                                       9056B642BEF870098DE344E5,
+                                       7DE81C004B0FBC563040CC5F,
+                                       2AB9A26C9359C40CA0A937ED,
+                                       A02C9F4C4B840C27B6CAFEBD,
+                                       50AFD116DCA6EC228EFB322D, ); runOnlyForDeploymentPostprocessing = 0; };
+               DE12B7643D374BFF7E4FEB1C = {isa = PBXNativeTarget; buildConfigurationList = E4ECAE24A646A7D1585F776C; buildPhases = (
+                                       2429BB4D705CC57F49418CFB,
+                                       E8E94B3C187DA578BFCBDA98,
+                                       C515A1FE1A53D3968C22FAEF, ); buildRules = ( ); dependencies = (  ); name = "AudioPluginHost - App"; productName = AudioPluginHost; productReference = 8D8BBC353637DA442C5575DA; productType = "com.apple.product-type.application"; };
+               ADE6E539DB98A302483A82D0 = {isa = PBXProject; buildConfigurationList = 493C2C5E457692E5149C5525; attributes = { LastUpgradeCheck = 0830; 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; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 65BEFC705A89E5C8A9E35C97; projectDirPath = ""; projectRoot = ""; targets = (DE12B7643D374BFF7E4FEB1C); };
+       };
+       rootObject = ADE6E539DB98A302483A82D0;
+}
diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Contents.json b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644 (file)
index 0000000..e216154
--- /dev/null
@@ -0,0 +1,158 @@
+{\r
+  "images": [\r
+    {\r
+      "idiom": "iphone",\r
+      "size": "20x20",\r
+      "filename": "Icon-Notification-20@2x.png",\r
+      "scale": "2x"\r
+    },\r
+    {\r
+      "idiom": "iphone",\r
+      "size": "20x20",\r
+      "filename": "Icon-Notification-20@3x.png",\r
+      "scale": "3x"\r
+    },\r
+    {\r
+      "idiom": "iphone",\r
+      "size": "29x29",\r
+      "filename": "Icon-29.png",\r
+      "scale": "1x"\r
+    },\r
+    {\r
+      "idiom": "iphone",\r
+      "size": "29x29",\r
+      "filename": "Icon-29@2x.png",\r
+      "scale": "2x"\r
+    },\r
+    {\r
+      "idiom": "iphone",\r
+      "size": "29x29",\r
+      "filename": "Icon-29@3x.png",\r
+      "scale": "3x"\r
+    },\r
+    {\r
+      "idiom": "iphone",\r
+      "size": "40x40",\r
+      "filename": "Icon-Spotlight-40@2x.png",\r
+      "scale": "2x"\r
+    },\r
+    {\r
+      "idiom": "iphone",\r
+      "size": "40x40",\r
+      "filename": "Icon-Spotlight-40@3x.png",\r
+      "scale": "3x"\r
+    },\r
+    {\r
+      "idiom": "iphone",\r
+      "size": "57x57",\r
+      "filename": "Icon.png",\r
+      "scale": "1x"\r
+    },\r
+    {\r
+      "idiom": "iphone",\r
+      "size": "57x57",\r
+      "filename": "Icon@2x.png",\r
+      "scale": "2x"\r
+    },\r
+    {\r
+      "idiom": "iphone",\r
+      "size": "60x60",\r
+      "filename": "Icon-60@2x.png",\r
+      "scale": "2x"\r
+    },\r
+    {\r
+      "idiom": "iphone",\r
+      "size": "60x60",\r
+      "filename": "Icon-@3x.png",\r
+      "scale": "3x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "20x20",\r
+      "filename": "Icon-Notifications-20.png",\r
+      "scale": "1x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "20x20",\r
+      "filename": "Icon-Notifications-20@2x.png",\r
+      "scale": "2x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "29x29",\r
+      "filename": "Icon-Small-1.png",\r
+      "scale": "1x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "29x29",\r
+      "filename": "Icon-Small@2x-1.png",\r
+      "scale": "2x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "40x40",\r
+      "filename": "Icon-Spotlight-40.png",\r
+      "scale": "1x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "40x40",\r
+      "filename": "Icon-Spotlight-40@2x-1.png",\r
+      "scale": "2x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "50x50",\r
+      "filename": "Icon-Small-50.png",\r
+      "scale": "1x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "50x50",\r
+      "filename": "Icon-Small-50@2x.png",\r
+      "scale": "2x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "72x72",\r
+      "filename": "Icon-72.png",\r
+      "scale": "1x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "72x72",\r
+      "filename": "Icon-72@2x.png",\r
+      "scale": "2x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "76x76",\r
+      "filename": "Icon-76.png",\r
+      "scale": "1x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "76x76",\r
+      "filename": "Icon-76@2x.png",\r
+      "scale": "2x"\r
+    },\r
+    {\r
+      "idiom": "ipad",\r
+      "size": "83.5x83.5",\r
+      "filename": "Icon-83.5@2x.png",\r
+      "scale": "2x"\r
+    },\r
+    {\r
+      "idiom": "ios-marketing",\r
+      "size": "1024x1024",\r
+      "filename": "Icon-AppStore-1024.png",\r
+      "scale": "1x"\r
+    }\r
+  ],\r
+  "info": {\r
+    "version": 1,\r
+    "author": "xcode"\r
+  }\r
+}
\ No newline at end of file
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
new file mode 100644 (file)
index 0000000..9344000
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-29.png differ
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
new file mode 100644 (file)
index 0000000..84a06c0
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-29@2x.png differ
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
new file mode 100644 (file)
index 0000000..6021b1d
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-29@3x.png differ
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
new file mode 100644 (file)
index 0000000..635a471
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png differ
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
new file mode 100644 (file)
index 0000000..52ec77a
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-72.png differ
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
new file mode 100644 (file)
index 0000000..54b2c96
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-72@2x.png differ
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
new file mode 100644 (file)
index 0000000..1d84eb4
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-76.png differ
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
new file mode 100644 (file)
index 0000000..4324c82
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png differ
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
new file mode 100644 (file)
index 0000000..c2cfbef
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png differ
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
new file mode 100644 (file)
index 0000000..15deee7
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-@3x.png differ
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
new file mode 100644 (file)
index 0000000..467fc9c
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-AppStore-1024.png differ
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
new file mode 100644 (file)
index 0000000..2a865c6
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notification-20@2x.png differ
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
new file mode 100644 (file)
index 0000000..ad988c8
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notification-20@3x.png differ
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
new file mode 100644 (file)
index 0000000..737b345
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notifications-20.png differ
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
new file mode 100644 (file)
index 0000000..2a865c6
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notifications-20@2x.png differ
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
new file mode 100644 (file)
index 0000000..9344000
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small-1.png differ
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
new file mode 100644 (file)
index 0000000..3328c84
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small-50.png differ
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
new file mode 100644 (file)
index 0000000..6650647
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png differ
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
new file mode 100644 (file)
index 0000000..84a06c0
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png differ
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
new file mode 100644 (file)
index 0000000..2a865c6
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png differ
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
new file mode 100644 (file)
index 0000000..680ebe0
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png differ
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
new file mode 100644 (file)
index 0000000..680ebe0
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png differ
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
new file mode 100644 (file)
index 0000000..635a471
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png differ
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
new file mode 100644 (file)
index 0000000..3ce58cf
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon.png differ
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
new file mode 100644 (file)
index 0000000..21c396f
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon@2x.png differ
diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/Contents.json b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/Contents.json
new file mode 100644 (file)
index 0000000..235448f
--- /dev/null
@@ -0,0 +1,57 @@
+{\r
+  "images": [\r
+    {\r
+      "orientation": "portrait",\r
+      "idiom": "iphone",\r
+      "extent": "full-screen",\r
+      "minimum-system-version": "7.0",\r
+      "scale": "2x",\r
+      "filename": "LaunchImage-iphone-2x.png"\r
+    },\r
+    {\r
+      "orientation": "portrait",\r
+      "idiom": "iphone",\r
+      "extent": "full-screen",\r
+      "minimum-system-version": "7.0",\r
+      "scale": "2x",\r
+      "filename": "LaunchImage-iphone-retina4.png",\r
+      "subtype": "retina4"\r
+    },\r
+    {\r
+      "orientation": "portrait",\r
+      "idiom": "ipad",\r
+      "extent": "full-screen",\r
+      "minimum-system-version": "7.0",\r
+      "scale": "1x",\r
+      "filename": "LaunchImage-ipad-portrait-1x.png"\r
+    },\r
+    {\r
+      "orientation": "landscape",\r
+      "idiom": "ipad",\r
+      "extent": "full-screen",\r
+      "minimum-system-version": "7.0",\r
+      "scale": "1x",\r
+      "filename": "LaunchImage-ipad-landscape-1x.png"\r
+    },\r
+    {\r
+      "orientation": "portrait",\r
+      "idiom": "ipad",\r
+      "extent": "full-screen",\r
+      "minimum-system-version": "7.0",\r
+      "scale": "2x",\r
+      "filename": "LaunchImage-ipad-portrait-2x.png"\r
+    },\r
+    {\r
+      "orientation": "landscape",\r
+      "idiom": "ipad",\r
+      "extent": "full-screen",\r
+      "minimum-system-version": "7.0",\r
+      "scale": "2x",\r
+      "filename": "LaunchImage-ipad-landscape-2x.png"\r
+    }\r
+  ],\r
+  "info": {\r
+    "version": 1,\r
+    "author": "xcode"\r
+  }\r
+}
\ No newline at end of file
diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-landscape-1x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-landscape-1x.png
new file mode 100644 (file)
index 0000000..b8a0025
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-landscape-1x.png differ
diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-landscape-2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-landscape-2x.png
new file mode 100644 (file)
index 0000000..817cdf8
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-landscape-2x.png differ
diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-portrait-1x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-portrait-1x.png
new file mode 100644 (file)
index 0000000..f368559
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-portrait-1x.png differ
diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-portrait-2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-portrait-2x.png
new file mode 100644 (file)
index 0000000..5447ddf
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-portrait-2x.png differ
diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-iphone-2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-iphone-2x.png
new file mode 100644 (file)
index 0000000..efe9e82
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-iphone-2x.png differ
diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-iphone-retina4.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-iphone-retina4.png
new file mode 100644 (file)
index 0000000..d0e3261
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/LaunchImage.launchimage/LaunchImage-iphone-retina4.png differ
diff --git a/extras/AudioPluginHost/Builds/iOS/Icon.icns b/extras/AudioPluginHost/Builds/iOS/Icon.icns
new file mode 100644 (file)
index 0000000..6ab6915
Binary files /dev/null and b/extras/AudioPluginHost/Builds/iOS/Icon.icns differ
diff --git a/extras/AudioPluginHost/Builds/iOS/Info-App.plist b/extras/AudioPluginHost/Builds/iOS/Info-App.plist
new file mode 100644 (file)
index 0000000..209e253
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+\r
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\r
+<plist>\r
+  <dict>\r
+    <key>LSRequiresIPhoneOS</key>\r
+    <true/>\r
+    <key>NSMicrophoneUsageDescription</key>\r
+    <string>This is an audio app which requires audio input. If you do not have a USB audio interface connected it will use the microphone.</string>\r
+    <key>UIViewControllerBasedStatusBarAppearance</key>\r
+    <false/>\r
+    <key>CFBundleExecutable</key>\r
+    <string>${EXECUTABLE_NAME}</string>\r
+    <key>CFBundleIdentifier</key>\r
+    <string>com.roli.juce.pluginhost</string>\r
+    <key>CFBundleName</key>\r
+    <string>AudioPluginHost</string>\r
+    <key>CFBundleDisplayName</key>\r
+    <string>AudioPluginHost</string>\r
+    <key>CFBundlePackageType</key>\r
+    <string>APPL</string>\r
+    <key>CFBundleSignature</key>\r
+    <string>????</string>\r
+    <key>CFBundleShortVersionString</key>\r
+    <string>1.0.0</string>\r
+    <key>CFBundleVersion</key>\r
+    <string>1.0.0</string>\r
+    <key>NSHumanReadableCopyright</key>\r
+    <string>ROLI Ltd.</string>\r
+    <key>NSHighResolutionCapable</key>\r
+    <true/>\r
+    <key>UIRequiresFullScreen</key>\r
+    <true/>\r
+    <key>UIStatusBarHidden</key>\r
+    <true/>\r
+    <key>UISupportedInterfaceOrientations</key>\r
+    <array>\r
+      <string>UIInterfaceOrientationPortrait</string>\r
+      <string>UIInterfaceOrientationLandscapeLeft</string>\r
+      <string>UIInterfaceOrientationLandscapeRight</string>\r
+    </array>\r
+    <key>UIBackgroundModes</key>\r
+    <array>\r
+      <string>audio</string>\r
+      <string>bluetooth-central</string>\r
+    </array>\r
+  </dict>\r
+</plist>\r
index 771e8aa9ef11b5eae23b31aba94028771e981631..a319a11eb7f4edba5409b4b8c8e5029c24b3dfe0 100644 (file)
@@ -16,7 +16,9 @@
 //==============================================================================\r
 // [BEGIN_USER_CODE_SECTION]\r
 \r
-// (You can add your own code in this section, and the Projucer will not overwrite it)\r
+#ifndef JUCE_ANDROID\r
+ #define JUCE_MODAL_LOOPS_PERMITTED   (! JUCE_IOS)\r
+#endif\r
 \r
 // [END_USER_CODE_SECTION]\r
 \r
  //#define JUCE_JACK 0\r
 #endif\r
 \r
+#ifndef    JUCE_BELA\r
+ //#define JUCE_BELA 0\r
+#endif\r
+\r
 #ifndef    JUCE_USE_ANDROID_OBOE\r
  //#define JUCE_USE_ANDROID_OBOE 0\r
 #endif\r
diff --git a/extras/AudioPluginHost/JuceLibraryCode/BinaryData.cpp b/extras/AudioPluginHost/JuceLibraryCode/BinaryData.cpp
new file mode 100644 (file)
index 0000000..8d0192f
--- /dev/null
@@ -0,0 +1,698 @@
+/* ==================================== JUCER_BINARY_RESOURCE ====================================\r
+\r
+   This is an auto-generated file: Any edits you make may be overwritten!\r
+\r
+*/\r
+\r
+namespace BinaryData\r
+{\r
+\r
+//================== JUCEAppIcon.png ==================\r
+static const unsigned char temp_binary_data_0[] =\r
+{ 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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+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,\r
+37,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };\r
+\r
+const char* JUCEAppIcon_png = (const char*) temp_binary_data_0;\r
+\r
+\r
+const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) noexcept\r
+{\r
+    unsigned int hash = 0;\r
+    if (resourceNameUTF8 != 0)\r
+        while (*resourceNameUTF8 != 0)\r
+            hash = 31 * hash + (unsigned int) *resourceNameUTF8++;\r
+\r
+    switch (hash)\r
+    {\r
+        case 0xdb43fd77:  numBytes = 45854; return JUCEAppIcon_png;\r
+        default: break;\r
+    }\r
+\r
+    numBytes = 0;\r
+    return nullptr;\r
+}\r
+\r
+const char* namedResourceList[] =\r
+{\r
+    "JUCEAppIcon_png"\r
+};\r
+\r
+const char* originalFilenames[] =\r
+{\r
+    "JUCEAppIcon.png"\r
+};\r
+\r
+const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8) noexcept\r
+{\r
+    for (unsigned int i = 0; i < (sizeof (namedResourceList) / sizeof (namedResourceList[0])); ++i)\r
+    {\r
+        if (namedResourceList[i] == resourceNameUTF8)\r
+            return originalFilenames[i];\r
+    }\r
+\r
+    return nullptr;\r
+}\r
+\r
+}\r
diff --git a/extras/AudioPluginHost/JuceLibraryCode/BinaryData.h b/extras/AudioPluginHost/JuceLibraryCode/BinaryData.h
new file mode 100644 (file)
index 0000000..60258e0
--- /dev/null
@@ -0,0 +1,30 @@
+/* =========================================================================================\r
+\r
+   This is an auto-generated file: Any edits you make may be overwritten!\r
+\r
+*/\r
+\r
+#pragma once\r
+\r
+namespace BinaryData\r
+{\r
+    extern const char*   JUCEAppIcon_png;\r
+    const int            JUCEAppIcon_pngSize = 45854;\r
+\r
+    // Number of elements in the namedResourceList and originalFileNames arrays.\r
+    const int namedResourceListSize = 1;\r
+\r
+    // Points to the start of a list of resource names.\r
+    extern const char* namedResourceList[];\r
+\r
+    // Points to the start of a list of resource filenames.\r
+    extern const char* originalFilenames[];\r
+\r
+    // If you provide the name of one of the binary resource variables above, this function will\r
+    // return the corresponding data and its size (or a null pointer if the name isn't found).\r
+    const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes) noexcept;\r
+\r
+    // If you provide the name of one of the binary resource variables above, this function will\r
+    // return the corresponding original, non-mangled filename (or a null pointer if the name isn't found).\r
+    const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8) noexcept;\r
+}\r
index f4dadd26692c94a029af4114ec9ec769e470026d..9d236c74b2f1da916c18c4b1576bc3984ffae016 100644 (file)
@@ -29,6 +29,7 @@
 #include <juce_opengl/juce_opengl.h>\r
 #include <juce_video/juce_video.h>\r
 \r
+#include "BinaryData.h"\r
 \r
 #if ! DONT_SET_USING_JUCE_NAMESPACE\r
  // If your code uses a lot of JUCE classes, then this will obviously save you\r
diff --git a/extras/AudioPluginHost/Source/FilterGraph.cpp b/extras/AudioPluginHost/Source/FilterGraph.cpp
deleted file mode 100644 (file)
index af1b97e..0000000
+++ /dev/null
@@ -1,456 +0,0 @@
-/*\r
-  ==============================================================================\r
-\r
-   This file is part of the JUCE library.\r
-   Copyright (c) 2017 - ROLI Ltd.\r
-\r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
-   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
-   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
-   27th April 2017).\r
-\r
-   End User License Agreement: www.juce.com/juce-5-licence\r
-   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
-   Or: You may also use this code under the terms of the GPL v3 (see\r
-   www.gnu.org/licenses).\r
-\r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
-\r
-  ==============================================================================\r
-*/\r
-\r
-#include "../JuceLibraryCode/JuceHeader.h"\r
-#include "MainHostWindow.h"\r
-#include "FilterGraph.h"\r
-#include "InternalFilters.h"\r
-#include "GraphEditorPanel.h"\r
-\r
-\r
-//==============================================================================\r
-FilterGraph::FilterGraph (AudioPluginFormatManager& fm)\r
-    : FileBasedDocument (getFilenameSuffix(),\r
-                         getFilenameWildcard(),\r
-                         "Load a filter graph",\r
-                         "Save a filter graph"),\r
-      formatManager (fm)\r
-{\r
-    newDocument();\r
-\r
-    graph.addListener (this);\r
-    graph.addChangeListener (this);\r
-\r
-    setChangedFlag (false);\r
-}\r
-\r
-FilterGraph::~FilterGraph()\r
-{\r
-    graph.addListener (this);\r
-    graph.removeChangeListener (this);\r
-    graph.clear();\r
-}\r
-\r
-FilterGraph::NodeID FilterGraph::getNextUID() noexcept\r
-{\r
-    return ++lastUID;\r
-}\r
-\r
-//==============================================================================\r
-void FilterGraph::changeListenerCallback (ChangeBroadcaster*)\r
-{\r
-    changed();\r
-\r
-    for (int i = activePluginWindows.size(); --i >= 0;)\r
-        if (! graph.getNodes().contains (activePluginWindows.getUnchecked(i)->node))\r
-            activePluginWindows.remove (i);\r
-}\r
-\r
-AudioProcessorGraph::Node::Ptr FilterGraph::getNodeForName (const String& name) const\r
-{\r
-    for (auto* node : graph.getNodes())\r
-        if (auto p = node->getProcessor())\r
-            if (p->getName().equalsIgnoreCase (name))\r
-                return node;\r
-\r
-    return nullptr;\r
-}\r
-\r
-void FilterGraph::addPlugin (const PluginDescription& desc, Point<double> p)\r
-{\r
-    struct AsyncCallback : public AudioPluginFormat::InstantiationCompletionCallback\r
-    {\r
-        AsyncCallback (FilterGraph& g, Point<double> pos)  : owner (g), position (pos)\r
-        {}\r
-\r
-        void completionCallback (AudioPluginInstance* instance, const String& error) override\r
-        {\r
-            owner.addFilterCallback (instance, error, position);\r
-        }\r
-\r
-        FilterGraph& owner;\r
-        Point<double> position;\r
-    };\r
-\r
-    formatManager.createPluginInstanceAsync (desc,\r
-                                             graph.getSampleRate(),\r
-                                             graph.getBlockSize(),\r
-                                             new AsyncCallback (*this, p));\r
-}\r
-\r
-void FilterGraph::addFilterCallback (AudioPluginInstance* instance, const String& error, Point<double> pos)\r
-{\r
-    if (instance == nullptr)\r
-    {\r
-        AlertWindow::showMessageBox (AlertWindow::WarningIcon,\r
-                                     TRANS("Couldn't create filter"),\r
-                                     error);\r
-    }\r
-    else\r
-    {\r
-        instance->enableAllBuses();\r
-\r
-        if (auto node = graph.addNode (instance))\r
-        {\r
-            node->properties.set ("x", pos.x);\r
-            node->properties.set ("y", pos.y);\r
-            changed();\r
-        }\r
-    }\r
-}\r
-\r
-void FilterGraph::setNodePosition (NodeID nodeID, Point<double> pos)\r
-{\r
-    if (auto* n = graph.getNodeForId (nodeID))\r
-    {\r
-        n->properties.set ("x", jlimit (0.0, 1.0, pos.x));\r
-        n->properties.set ("y", jlimit (0.0, 1.0, pos.y));\r
-    }\r
-}\r
-\r
-Point<double> FilterGraph::getNodePosition (NodeID nodeID) const\r
-{\r
-    if (auto* n = graph.getNodeForId (nodeID))\r
-        return { static_cast<double> (n->properties ["x"]),\r
-                 static_cast<double> (n->properties ["y"]) };\r
-\r
-    return {};\r
-}\r
-\r
-//==============================================================================\r
-void FilterGraph::clear()\r
-{\r
-    closeAnyOpenPluginWindows();\r
-    graph.clear();\r
-    changed();\r
-}\r
-\r
-PluginWindow* FilterGraph::getOrCreateWindowFor (AudioProcessorGraph::Node* node, PluginWindow::Type type)\r
-{\r
-    jassert (node != nullptr);\r
-\r
-    for (auto* w : activePluginWindows)\r
-        if (w->node == node && w->type == type)\r
-            return w;\r
-\r
-    if (auto* processor = node->getProcessor())\r
-    {\r
-        if (auto* plugin = dynamic_cast<AudioPluginInstance*> (processor))\r
-        {\r
-            auto description = plugin->getPluginDescription();\r
-\r
-            if (description.pluginFormatName == "Internal")\r
-            {\r
-                getCommandManager().invokeDirectly (CommandIDs::showAudioSettings, false);\r
-                return nullptr;\r
-            }\r
-        }\r
-\r
-        return activePluginWindows.add (new PluginWindow (node, type, activePluginWindows));\r
-    }\r
-\r
-    return nullptr;\r
-}\r
-\r
-bool FilterGraph::closeAnyOpenPluginWindows()\r
-{\r
-    bool wasEmpty = activePluginWindows.isEmpty();\r
-    activePluginWindows.clear();\r
-    return ! wasEmpty;\r
-}\r
-\r
-//==============================================================================\r
-String FilterGraph::getDocumentTitle()\r
-{\r
-    if (! getFile().exists())\r
-        return "Unnamed";\r
-\r
-    return getFile().getFileNameWithoutExtension();\r
-}\r
-\r
-void FilterGraph::newDocument()\r
-{\r
-    clear();\r
-    setFile ({});\r
-\r
-    InternalPluginFormat internalFormat;\r
-\r
-    addPlugin (internalFormat.audioInDesc,  { 0.5,  0.1 });\r
-    addPlugin (internalFormat.midiInDesc,   { 0.25, 0.1 });\r
-    addPlugin (internalFormat.audioOutDesc, { 0.5,  0.9 });\r
-\r
-    setChangedFlag (false);\r
-}\r
-\r
-Result FilterGraph::loadDocument (const File& file)\r
-{\r
-    XmlDocument doc (file);\r
-    ScopedPointer<XmlElement> xml (doc.getDocumentElement());\r
-\r
-    if (xml == nullptr || ! xml->hasTagName ("FILTERGRAPH"))\r
-        return Result::fail ("Not a valid filter graph file");\r
-\r
-    restoreFromXml (*xml);\r
-    return Result::ok();\r
-}\r
-\r
-Result FilterGraph::saveDocument (const File& file)\r
-{\r
-    ScopedPointer<XmlElement> xml (createXml());\r
-\r
-    if (! xml->writeToFile (file, {}))\r
-        return Result::fail ("Couldn't write to the file");\r
-\r
-    return Result::ok();\r
-}\r
-\r
-File FilterGraph::getLastDocumentOpened()\r
-{\r
-    RecentlyOpenedFilesList recentFiles;\r
-    recentFiles.restoreFromString (getAppProperties().getUserSettings()\r
-                                        ->getValue ("recentFilterGraphFiles"));\r
-\r
-    return recentFiles.getFile (0);\r
-}\r
-\r
-void FilterGraph::setLastDocumentOpened (const File& file)\r
-{\r
-    RecentlyOpenedFilesList recentFiles;\r
-    recentFiles.restoreFromString (getAppProperties().getUserSettings()\r
-                                        ->getValue ("recentFilterGraphFiles"));\r
-\r
-    recentFiles.addFile (file);\r
-\r
-    getAppProperties().getUserSettings()\r
-        ->setValue ("recentFilterGraphFiles", recentFiles.toString());\r
-}\r
-\r
-//==============================================================================\r
-static void readBusLayoutFromXml (AudioProcessor::BusesLayout& busesLayout, AudioProcessor* plugin,\r
-                                  const XmlElement& xml, const bool isInput)\r
-{\r
-    auto& targetBuses = (isInput ? busesLayout.inputBuses\r
-                                 : busesLayout.outputBuses);\r
-    int maxNumBuses = 0;\r
-\r
-    if (auto* buses = xml.getChildByName (isInput ? "INPUTS" : "OUTPUTS"))\r
-    {\r
-        forEachXmlChildElementWithTagName (*buses, e, "BUS")\r
-        {\r
-            const int busIdx = e->getIntAttribute ("index");\r
-            maxNumBuses = jmax (maxNumBuses, busIdx + 1);\r
-\r
-            // the number of buses on busesLayout may not be in sync with the plugin after adding buses\r
-            // because adding an input bus could also add an output bus\r
-            for (int actualIdx = plugin->getBusCount (isInput) - 1; actualIdx < busIdx; ++actualIdx)\r
-                if (! plugin->addBus (isInput))\r
-                    return;\r
-\r
-            for (int actualIdx = targetBuses.size() - 1; actualIdx < busIdx; ++actualIdx)\r
-                targetBuses.add (plugin->getChannelLayoutOfBus (isInput, busIdx));\r
-\r
-            auto layout = e->getStringAttribute ("layout");\r
-\r
-            if (layout.isNotEmpty())\r
-                targetBuses.getReference (busIdx) = AudioChannelSet::fromAbbreviatedString (layout);\r
-        }\r
-    }\r
-\r
-    // if the plugin has more buses than specified in the xml, then try to remove them!\r
-    while (maxNumBuses < targetBuses.size())\r
-    {\r
-        if (! plugin->removeBus (isInput))\r
-            return;\r
-\r
-        targetBuses.removeLast();\r
-    }\r
-}\r
-\r
-//==============================================================================\r
-static XmlElement* createBusLayoutXml (const AudioProcessor::BusesLayout& layout, const bool isInput)\r
-{\r
-    auto& buses = isInput ? layout.inputBuses\r
-                          : layout.outputBuses;\r
-\r
-    auto* xml = new XmlElement (isInput ? "INPUTS" : "OUTPUTS");\r
-\r
-    for (int busIdx = 0; busIdx < buses.size(); ++busIdx)\r
-    {\r
-        auto& set = buses.getReference (busIdx);\r
-\r
-        auto* bus = xml->createNewChildElement ("BUS");\r
-        bus->setAttribute ("index", busIdx);\r
-        bus->setAttribute ("layout", set.isDisabled() ? "disabled" : set.getSpeakerArrangementAsString());\r
-    }\r
-\r
-    return xml;\r
-}\r
-\r
-static XmlElement* createNodeXml (AudioProcessorGraph::Node* const node) noexcept\r
-{\r
-    if (auto* plugin = dynamic_cast<AudioPluginInstance*> (node->getProcessor()))\r
-    {\r
-        auto e = new XmlElement ("FILTER");\r
-        e->setAttribute ("uid", (int) node->nodeID);\r
-        e->setAttribute ("x", node->properties ["x"].toString());\r
-        e->setAttribute ("y", node->properties ["y"].toString());\r
-\r
-        for (int i = 0; i < (int) PluginWindow::Type::numTypes; ++i)\r
-        {\r
-            auto type = (PluginWindow::Type) i;\r
-\r
-            if (node->properties.contains (PluginWindow::getOpenProp (type)))\r
-            {\r
-                e->setAttribute (PluginWindow::getLastXProp (type), node->properties[PluginWindow::getLastXProp (type)].toString());\r
-                e->setAttribute (PluginWindow::getLastYProp (type), node->properties[PluginWindow::getLastYProp (type)].toString());\r
-                e->setAttribute (PluginWindow::getOpenProp (type),  node->properties[PluginWindow::getOpenProp (type)].toString());\r
-            }\r
-        }\r
-\r
-        {\r
-            PluginDescription pd;\r
-            plugin->fillInPluginDescription (pd);\r
-            e->addChildElement (pd.createXml());\r
-        }\r
-\r
-        {\r
-            MemoryBlock m;\r
-            node->getProcessor()->getStateInformation (m);\r
-            e->createNewChildElement ("STATE")->addTextElement (m.toBase64Encoding());\r
-        }\r
-\r
-        auto layout = plugin->getBusesLayout();\r
-\r
-        auto layouts = e->createNewChildElement ("LAYOUT");\r
-        layouts->addChildElement (createBusLayoutXml (layout, true));\r
-        layouts->addChildElement (createBusLayoutXml (layout, false));\r
-\r
-        return e;\r
-    }\r
-\r
-    jassertfalse;\r
-    return nullptr;\r
-}\r
-\r
-void FilterGraph::createNodeFromXml (const XmlElement& xml)\r
-{\r
-    PluginDescription pd;\r
-\r
-    forEachXmlChildElement (xml, e)\r
-    {\r
-        if (pd.loadFromXml (*e))\r
-            break;\r
-    }\r
-\r
-    String errorMessage;\r
-\r
-    if (auto* instance = formatManager.createPluginInstance (pd, graph.getSampleRate(),\r
-                                                             graph.getBlockSize(), errorMessage))\r
-    {\r
-        if (auto* layoutEntity = xml.getChildByName ("LAYOUT"))\r
-        {\r
-            auto layout = instance->getBusesLayout();\r
-\r
-            readBusLayoutFromXml (layout, instance, *layoutEntity, true);\r
-            readBusLayoutFromXml (layout, instance, *layoutEntity, false);\r
-\r
-            instance->setBusesLayout (layout);\r
-        }\r
-\r
-        if (auto node = graph.addNode (instance, (NodeID) xml.getIntAttribute ("uid")))\r
-        {\r
-            if (auto* state = xml.getChildByName ("STATE"))\r
-            {\r
-                MemoryBlock m;\r
-                m.fromBase64Encoding (state->getAllSubText());\r
-\r
-                node->getProcessor()->setStateInformation (m.getData(), (int) m.getSize());\r
-            }\r
-\r
-            node->properties.set ("x", xml.getDoubleAttribute ("x"));\r
-            node->properties.set ("y", xml.getDoubleAttribute ("y"));\r
-\r
-            for (int i = 0; i < (int) PluginWindow::Type::numTypes; ++i)\r
-            {\r
-                auto type = (PluginWindow::Type) i;\r
-\r
-                if (xml.hasAttribute (PluginWindow::getOpenProp (type)))\r
-                {\r
-                    node->properties.set (PluginWindow::getLastXProp (type), xml.getIntAttribute (PluginWindow::getLastXProp (type)));\r
-                    node->properties.set (PluginWindow::getLastYProp (type), xml.getIntAttribute (PluginWindow::getLastYProp (type)));\r
-                    node->properties.set (PluginWindow::getOpenProp  (type), xml.getIntAttribute (PluginWindow::getOpenProp (type)));\r
-\r
-                    if (node->properties[PluginWindow::getOpenProp (type)])\r
-                    {\r
-                        jassert (node->getProcessor() != nullptr);\r
-\r
-                        if (auto w = getOrCreateWindowFor (node, type))\r
-                            w->toFront (true);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-    }\r
-}\r
-\r
-XmlElement* FilterGraph::createXml() const\r
-{\r
-    auto* xml = new XmlElement ("FILTERGRAPH");\r
-\r
-    for (auto* node : graph.getNodes())\r
-        xml->addChildElement (createNodeXml (node));\r
-\r
-    for (auto& connection : graph.getConnections())\r
-    {\r
-        auto e = xml->createNewChildElement ("CONNECTION");\r
-\r
-        e->setAttribute ("srcFilter", (int) connection.source.nodeID);\r
-        e->setAttribute ("srcChannel", connection.source.channelIndex);\r
-        e->setAttribute ("dstFilter", (int) connection.destination.nodeID);\r
-        e->setAttribute ("dstChannel", connection.destination.channelIndex);\r
-    }\r
-\r
-    return xml;\r
-}\r
-\r
-void FilterGraph::restoreFromXml (const XmlElement& xml)\r
-{\r
-    clear();\r
-\r
-    forEachXmlChildElementWithTagName (xml, e, "FILTER")\r
-    {\r
-        createNodeFromXml (*e);\r
-        changed();\r
-    }\r
-\r
-    forEachXmlChildElementWithTagName (xml, e, "CONNECTION")\r
-    {\r
-        graph.addConnection ({ { (NodeID) e->getIntAttribute ("srcFilter"), e->getIntAttribute ("srcChannel") },\r
-                               { (NodeID) e->getIntAttribute ("dstFilter"), e->getIntAttribute ("dstChannel") } });\r
-    }\r
-\r
-    graph.removeIllegalConnections();\r
-}\r
diff --git a/extras/AudioPluginHost/Source/FilterGraph.h b/extras/AudioPluginHost/Source/FilterGraph.h
deleted file mode 100644 (file)
index 5a26093..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*\r
-  ==============================================================================\r
-\r
-   This file is part of the JUCE library.\r
-   Copyright (c) 2017 - ROLI Ltd.\r
-\r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
-   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
-   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
-   27th April 2017).\r
-\r
-   End User License Agreement: www.juce.com/juce-5-licence\r
-   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
-   Or: You may also use this code under the terms of the GPL v3 (see\r
-   www.gnu.org/licenses).\r
-\r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
-\r
-  ==============================================================================\r
-*/\r
-\r
-#pragma once\r
-\r
-#include "PluginWindow.h"\r
-\r
-\r
-//==============================================================================\r
-/**\r
-    A collection of filters and some connections between them.\r
-*/\r
-class FilterGraph   : public FileBasedDocument,\r
-                      public AudioProcessorListener,\r
-                      private ChangeListener\r
-{\r
-public:\r
-    //==============================================================================\r
-    FilterGraph (AudioPluginFormatManager&);\r
-    ~FilterGraph();\r
-\r
-    //==============================================================================\r
-    typedef AudioProcessorGraph::NodeID NodeID;\r
-\r
-    void addPlugin (const PluginDescription&, Point<double>);\r
-\r
-    AudioProcessorGraph::Node::Ptr getNodeForName (const String& name) const;\r
-\r
-    void setNodePosition (NodeID, Point<double>);\r
-    Point<double> getNodePosition (NodeID) const;\r
-\r
-    //==============================================================================\r
-    void clear();\r
-\r
-    PluginWindow* getOrCreateWindowFor (AudioProcessorGraph::Node*, PluginWindow::Type);\r
-    void closeCurrentlyOpenWindowsFor (AudioProcessorGraph::NodeID);\r
-    bool closeAnyOpenPluginWindows();\r
-\r
-    //==============================================================================\r
-    void audioProcessorParameterChanged (AudioProcessor*, int, float) override {}\r
-    void audioProcessorChanged (AudioProcessor*) override { changed(); }\r
-\r
-    //==============================================================================\r
-    XmlElement* createXml() const;\r
-    void restoreFromXml (const XmlElement& xml);\r
-\r
-    static const char* getFilenameSuffix()      { return ".filtergraph"; }\r
-    static const char* getFilenameWildcard()    { return "*.filtergraph"; }\r
-\r
-    //==============================================================================\r
-    void newDocument();\r
-    String getDocumentTitle() override;\r
-    Result loadDocument (const File& file) override;\r
-    Result saveDocument (const File& file) override;\r
-    File getLastDocumentOpened() override;\r
-    void setLastDocumentOpened (const File& file) override;\r
-\r
-    //==============================================================================\r
-    AudioProcessorGraph graph;\r
-\r
-private:\r
-    //==============================================================================\r
-    AudioPluginFormatManager& formatManager;\r
-    OwnedArray<PluginWindow> activePluginWindows;\r
-\r
-    NodeID lastUID = 0;\r
-    NodeID getNextUID() noexcept;\r
-\r
-    void createNodeFromXml (const XmlElement& xml);\r
-    void addFilterCallback (AudioPluginInstance*, const String& error, Point<double>);\r
-    void changeListenerCallback (ChangeBroadcaster*) override;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilterGraph)\r
-};\r
diff --git a/extras/AudioPluginHost/Source/FilterIOConfiguration.cpp b/extras/AudioPluginHost/Source/FilterIOConfiguration.cpp
deleted file mode 100644 (file)
index 646e8dc..0000000
+++ /dev/null
@@ -1,548 +0,0 @@
-/*\r
-  ==============================================================================\r
-\r
-   This file is part of the JUCE library.\r
-   Copyright (c) 2017 - ROLI Ltd.\r
-\r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
-   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
-   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
-   27th April 2017).\r
-\r
-   End User License Agreement: www.juce.com/juce-5-licence\r
-   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
-   Or: You may also use this code under the terms of the GPL v3 (see\r
-   www.gnu.org/licenses).\r
-\r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
-\r
-  ==============================================================================\r
-*/\r
-\r
-#include "../JuceLibraryCode/JuceHeader.h"\r
-#include "GraphEditorPanel.h"\r
-#include "InternalFilters.h"\r
-#include "MainHostWindow.h"\r
-#include "FilterIOConfiguration.h"\r
-\r
-\r
-//==============================================================================\r
-struct NumberedBoxes  : public TableListBox,\r
-                        private TableListBoxModel,\r
-                        private Button::Listener\r
-{\r
-    struct Listener\r
-    {\r
-        virtual ~Listener() {}\r
-\r
-        virtual void addColumn()    = 0;\r
-        virtual void removeColumn() = 0;\r
-        virtual void columnSelected (int columnId) = 0;\r
-    };\r
-\r
-    enum\r
-    {\r
-        plusButtonColumnId  = 128,\r
-        minusButtonColumnId = 129\r
-    };\r
-\r
-    //==============================================================================\r
-    NumberedBoxes (Listener& listenerToUse, bool canCurrentlyAddColumn, bool canCurrentlyRemoveColumn)\r
-        : TableListBox ("NumberedBoxes", this),\r
-          listener (listenerToUse),\r
-          canAddColumn (canCurrentlyAddColumn),\r
-          canRemoveColumn (canCurrentlyRemoveColumn)\r
-    {\r
-        auto& tableHeader = getHeader();\r
-\r
-        for (int i = 0; i < 16; ++i)\r
-            tableHeader.addColumn (String (i + 1), i + 1, 40);\r
-\r
-        setHeaderHeight (0);\r
-        setRowHeight (40);\r
-        getHorizontalScrollBar().setAutoHide (false);\r
-    }\r
-\r
-    void setSelected (int columnId)\r
-    {\r
-        if (auto* button = dynamic_cast<TextButton*> (getCellComponent (columnId, 0)))\r
-            button->setToggleState (true, NotificationType::dontSendNotification);\r
-    }\r
-\r
-    void setCanAddColumn (bool canCurrentlyAdd)\r
-    {\r
-        if (canCurrentlyAdd != canAddColumn)\r
-        {\r
-            canAddColumn = canCurrentlyAdd;\r
-\r
-            if (auto* button = dynamic_cast<TextButton*> (getCellComponent (plusButtonColumnId, 0)))\r
-                button->setEnabled (true);\r
-        }\r
-    }\r
-\r
-    void setCanRemoveColumn (bool canCurrentlyRemove)\r
-    {\r
-        if (canCurrentlyRemove != canRemoveColumn)\r
-        {\r
-            canRemoveColumn = canCurrentlyRemove;\r
-\r
-            if (auto* button = dynamic_cast<TextButton*> (getCellComponent (minusButtonColumnId, 0)))\r
-                button->setEnabled (true);\r
-        }\r
-    }\r
-\r
-private:\r
-    //==============================================================================\r
-    Listener& listener;\r
-    bool canAddColumn, canRemoveColumn;\r
-\r
-    //==============================================================================\r
-    int getNumRows() override                                             { return 1; }\r
-    void paintCell (Graphics&, int, int, int, int, bool) override         {}\r
-    void paintRowBackground (Graphics& g, int, int, int, bool) override   { g.fillAll (Colours::grey); }\r
-\r
-    Component* refreshComponentForCell (int, int columnId, bool,\r
-                                        Component* existingComponentToUpdate) override\r
-    {\r
-        auto* textButton = dynamic_cast<TextButton*> (existingComponentToUpdate);\r
-\r
-        if (textButton == nullptr)\r
-            textButton = new TextButton();\r
-\r
-        textButton->setButtonText (getButtonName (columnId));\r
-        textButton->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight |\r
-                                       Button::ConnectedOnTop  | Button::ConnectedOnBottom);\r
-\r
-        const bool isPlusMinusButton = (columnId == plusButtonColumnId || columnId == minusButtonColumnId);\r
-\r
-        if (isPlusMinusButton)\r
-        {\r
-            textButton->setEnabled (columnId == plusButtonColumnId ? canAddColumn : canRemoveColumn);\r
-        }\r
-        else\r
-        {\r
-            textButton->setRadioGroupId (1, NotificationType::dontSendNotification);\r
-            textButton->setClickingTogglesState (true);\r
-\r
-            auto busColour = Colours::green.withRotatedHue (static_cast<float> (columnId) / 5.0f);\r
-            textButton->setColour (TextButton::buttonColourId, busColour);\r
-            textButton->setColour (TextButton::buttonOnColourId, busColour.withMultipliedBrightness (2.0f));\r
-        }\r
-\r
-        textButton->addListener (this);\r
-\r
-        return textButton;\r
-    }\r
-\r
-    //==============================================================================\r
-    String getButtonName (int columnId)\r
-    {\r
-        if (columnId == plusButtonColumnId)  return "+";\r
-        if (columnId == minusButtonColumnId) return "-";\r
-\r
-        return String (columnId);\r
-    }\r
-\r
-    void buttonClicked (Button* btn) override\r
-    {\r
-        auto text = btn->getButtonText();\r
-\r
-        if (text == "+") listener.addColumn();\r
-        if (text == "-") listener.removeColumn();\r
-    }\r
-\r
-    void buttonStateChanged (Button* btn) override\r
-    {\r
-        auto text = btn->getButtonText();\r
-\r
-        if (text == "+" || text == "-")\r
-            return;\r
-\r
-        if (btn->getToggleState())\r
-            listener.columnSelected (text.getIntValue());\r
-    }\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NumberedBoxes)\r
-};\r
-\r
-//==============================================================================\r
-class FilterIOConfigurationWindow::InputOutputConfig  : public Component,\r
-                                                        private ComboBox::Listener,\r
-                                                        private Button::Listener,\r
-                                                        private NumberedBoxes::Listener\r
-{\r
-public:\r
-    InputOutputConfig (FilterIOConfigurationWindow& parent, bool direction)\r
-        : owner (parent),\r
-          ioTitle ("ioLabel", direction ? "Input Configuration" : "Output Configuration"),\r
-          ioBuses (*this, false, false),\r
-          isInput (direction)\r
-    {\r
-        ioTitle.setFont (ioTitle.getFont().withStyle (Font::bold));\r
-        nameLabel.setFont (nameLabel.getFont().withStyle (Font::bold));\r
-        layoutLabel.setFont (layoutLabel.getFont().withStyle (Font::bold));\r
-        enabledToggle.setClickingTogglesState (true);\r
-\r
-        layouts.addListener (this);\r
-        enabledToggle.addListener (this);\r
-\r
-        addAndMakeVisible (layoutLabel);\r
-        addAndMakeVisible (layouts);\r
-        addAndMakeVisible (enabledToggle);\r
-        addAndMakeVisible (ioTitle);\r
-        addAndMakeVisible (nameLabel);\r
-        addAndMakeVisible (name);\r
-        addAndMakeVisible (ioBuses);\r
-\r
-        updateBusButtons();\r
-        updateBusLayout();\r
-    }\r
-\r
-    void paint (Graphics& g) override\r
-    {\r
-        g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r
-    }\r
-\r
-    void resized() override\r
-    {\r
-        auto r = getLocalBounds().reduced (10);\r
-\r
-        ioTitle.setBounds (r.removeFromTop (14));\r
-        r.reduce (10, 0);\r
-        r.removeFromTop (16);\r
-\r
-        ioBuses.setBounds (r.removeFromTop (60));\r
-\r
-        {\r
-            auto label = r.removeFromTop (24);\r
-            nameLabel.setBounds (label.removeFromLeft (100));\r
-            enabledToggle.setBounds (label.removeFromRight (80));\r
-            name.setBounds (label);\r
-        }\r
-\r
-        {\r
-            auto label = r.removeFromTop (24);\r
-            layoutLabel.setBounds (label.removeFromLeft (100));\r
-            layouts.setBounds (label);\r
-        }\r
-    }\r
-\r
-private:\r
-    void updateBusButtons()\r
-    {\r
-        if (auto* filter = owner.getAudioProcessor())\r
-        {\r
-            auto& header = ioBuses.getHeader();\r
-            header.removeAllColumns();\r
-\r
-            const int n = filter->getBusCount (isInput);\r
-\r
-            for (int i = 0; i < n; ++i)\r
-                header.addColumn ("", i + 1, 40);\r
-\r
-            header.addColumn ("+", NumberedBoxes::plusButtonColumnId,  20);\r
-            header.addColumn ("-", NumberedBoxes::minusButtonColumnId, 20);\r
-\r
-            ioBuses.setCanAddColumn    (filter->canAddBus    (isInput));\r
-            ioBuses.setCanRemoveColumn (filter->canRemoveBus (isInput));\r
-        }\r
-\r
-        ioBuses.setSelected (currentBus + 1);\r
-    }\r
-\r
-    void updateBusLayout()\r
-    {\r
-        if (auto* filter = owner.getAudioProcessor())\r
-        {\r
-            if (auto* bus = filter->getBus (isInput, currentBus))\r
-            {\r
-                name.setText (bus->getName(), NotificationType::dontSendNotification);\r
-\r
-                int i;\r
-                for (i = 1; i < AudioChannelSet::maxChannelsOfNamedLayout; ++i)\r
-                    if ((layouts.indexOfItemId(i) == -1) != bus->supportedLayoutWithChannels (i).isDisabled())\r
-                        break;\r
-\r
-                // supported layouts have changed\r
-                if (i < AudioChannelSet::maxChannelsOfNamedLayout)\r
-                {\r
-                    layouts.clear();\r
-\r
-                    for (i = 1; i < AudioChannelSet::maxChannelsOfNamedLayout; ++i)\r
-                    {\r
-                        auto set = bus->supportedLayoutWithChannels (i);\r
-\r
-                        if (! set.isDisabled())\r
-                            layouts.addItem (set.getDescription(), i);\r
-                    }\r
-                }\r
-\r
-                layouts.setSelectedId (bus->getLastEnabledLayout().size());\r
-\r
-                const bool canBeDisabled = bus->isNumberOfChannelsSupported (0);\r
-\r
-                if (canBeDisabled != enabledToggle.isEnabled())\r
-                    enabledToggle.setEnabled (canBeDisabled);\r
-\r
-                enabledToggle.setToggleState (bus->isEnabled(), NotificationType::dontSendNotification);\r
-            }\r
-        }\r
-    }\r
-\r
-    //==============================================================================\r
-    void comboBoxChanged (ComboBox* combo) override\r
-    {\r
-        if (combo == &layouts)\r
-        {\r
-            if (auto* p = owner.getAudioProcessor())\r
-            {\r
-                if (auto* bus = p->getBus (isInput, currentBus))\r
-                {\r
-                    auto selectedNumChannels = layouts.getSelectedId();\r
-\r
-                    if (selectedNumChannels != bus->getLastEnabledLayout().size())\r
-                    {\r
-                        if (isPositiveAndBelow (selectedNumChannels, AudioChannelSet::maxChannelsOfNamedLayout)\r
-                             && bus->setCurrentLayoutWithoutEnabling (bus->supportedLayoutWithChannels (selectedNumChannels)))\r
-                        {\r
-                            if (auto* config = owner.getConfig (! isInput))\r
-                                config->updateBusLayout();\r
-\r
-                            owner.update();\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    void buttonClicked (Button*) override {}\r
-\r
-    void buttonStateChanged (Button* btn) override\r
-    {\r
-        if (btn == &enabledToggle && enabledToggle.isEnabled())\r
-        {\r
-            if (auto* p = owner.getAudioProcessor())\r
-            {\r
-                if (auto* bus = p->getBus (isInput, currentBus))\r
-                {\r
-                    if (bus->isEnabled() != enabledToggle.getToggleState())\r
-                    {\r
-                        bool success = enabledToggle.getToggleState() ? bus->enable()\r
-                                                                      : bus->setCurrentLayout (AudioChannelSet::disabled());\r
-\r
-                        if (success)\r
-                        {\r
-                            updateBusLayout();\r
-\r
-                            if (auto* config = owner.getConfig (! isInput))\r
-                                config->updateBusLayout();\r
-\r
-                            owner.update();\r
-                        }\r
-                        else\r
-                        {\r
-                            enabledToggle.setToggleState (! enabledToggle.getToggleState(),\r
-                                                          NotificationType::dontSendNotification);\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    //==============================================================================\r
-    void addColumn() override\r
-    {\r
-        if (auto* p = owner.getAudioProcessor())\r
-        {\r
-            if (p->canAddBus (isInput))\r
-            {\r
-                if (p->addBus (isInput))\r
-                {\r
-                    updateBusButtons();\r
-                    updateBusLayout();\r
-\r
-                    if (auto* config = owner.getConfig (! isInput))\r
-                    {\r
-                        config->updateBusButtons();\r
-                        config->updateBusLayout();\r
-                    }\r
-                }\r
-\r
-                owner.update();\r
-            }\r
-        }\r
-    }\r
-\r
-    void removeColumn() override\r
-    {\r
-        if (auto* p = owner.getAudioProcessor())\r
-        {\r
-            if (p->getBusCount (isInput) > 1 && p->canRemoveBus (isInput))\r
-            {\r
-                if (p->removeBus (isInput))\r
-                {\r
-                    currentBus = jmin (p->getBusCount (isInput) - 1, currentBus);\r
-\r
-                    updateBusButtons();\r
-                    updateBusLayout();\r
-\r
-                    if (auto* config = owner.getConfig (! isInput))\r
-                    {\r
-                        config->updateBusButtons();\r
-                        config->updateBusLayout();\r
-                    }\r
-\r
-                    owner.update();\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    void columnSelected (int columnId) override\r
-    {\r
-        const int newBus = columnId - 1;\r
-\r
-        if (currentBus != newBus)\r
-        {\r
-            currentBus = newBus;\r
-            ioBuses.setSelected (currentBus + 1);\r
-            updateBusLayout();\r
-        }\r
-    }\r
-\r
-    //==============================================================================\r
-    FilterIOConfigurationWindow& owner;\r
-    Label ioTitle, name;\r
-    Label nameLabel { "nameLabel", "Bus Name:" };\r
-    Label layoutLabel { "layoutLabel", "Channel Layout:" };\r
-    ToggleButton enabledToggle { "Enabled" };\r
-    ComboBox layouts;\r
-    NumberedBoxes ioBuses;\r
-    bool isInput;\r
-    int currentBus = 0;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InputOutputConfig)\r
-};\r
-\r
-\r
-FilterIOConfigurationWindow::FilterIOConfigurationWindow (AudioProcessor& p)\r
-   : AudioProcessorEditor (&p),\r
-     title ("title", p.getName())\r
-{\r
-    setOpaque (true);\r
-\r
-    title.setFont (title.getFont().withStyle (Font::bold));\r
-    addAndMakeVisible (title);\r
-\r
-    {\r
-        ScopedLock renderLock (p.getCallbackLock());\r
-        p.suspendProcessing (true);\r
-        p.releaseResources();\r
-    }\r
-\r
-    if (p.getBusCount (true)  > 0 || p.canAddBus (true))\r
-        addAndMakeVisible (inConfig = new InputOutputConfig (*this, true));\r
-\r
-    if (p.getBusCount (false) > 0 || p.canAddBus (false))\r
-        addAndMakeVisible (outConfig = new InputOutputConfig (*this, false));\r
-\r
-    currentLayout = p.getBusesLayout();\r
-    setSize (400, (inConfig != nullptr && outConfig != nullptr ? 160 : 0) + 200);\r
-}\r
-\r
-FilterIOConfigurationWindow::~FilterIOConfigurationWindow()\r
-{\r
-    if (auto* graph = getGraph())\r
-    {\r
-        if (auto* p = getAudioProcessor())\r
-        {\r
-            ScopedLock renderLock (graph->getCallbackLock());\r
-\r
-            graph->suspendProcessing (true);\r
-            graph->releaseResources();\r
-\r
-            p->prepareToPlay (graph->getSampleRate(), graph->getBlockSize());\r
-            p->suspendProcessing (false);\r
-\r
-            graph->prepareToPlay (graph->getSampleRate(), graph->getBlockSize());\r
-            graph->suspendProcessing (false);\r
-        }\r
-    }\r
-}\r
-\r
-void FilterIOConfigurationWindow::paint (Graphics& g)\r
-{\r
-     g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r
-}\r
-\r
-void FilterIOConfigurationWindow::resized()\r
-{\r
-    auto r = getLocalBounds().reduced (10);\r
-\r
-    title.setBounds (r.removeFromTop (14));\r
-    r.reduce (10, 0);\r
-\r
-    if (inConfig != nullptr)\r
-        inConfig->setBounds (r.removeFromTop (160));\r
-\r
-    if (outConfig != nullptr)\r
-        outConfig->setBounds (r.removeFromTop (160));\r
-}\r
-\r
-void FilterIOConfigurationWindow::update()\r
-{\r
-    auto nodeID = getNodeID();\r
-\r
-    if (auto* graph = getGraph())\r
-        if (nodeID != 0)\r
-            graph->disconnectNode (nodeID);\r
-\r
-    if (auto* graphEditor = getGraphEditor())\r
-        if (auto* panel = graphEditor->graphPanel.get())\r
-            panel->updateComponents();\r
-}\r
-\r
-AudioProcessorGraph::NodeID FilterIOConfigurationWindow::getNodeID() const\r
-{\r
-    if (auto* graph = getGraph())\r
-        for (auto* node : graph->getNodes())\r
-            if (node->getProcessor() == getAudioProcessor())\r
-                return node->nodeID;\r
-\r
-    return 0;\r
-}\r
-\r
-MainHostWindow* FilterIOConfigurationWindow::getMainWindow() const\r
-{\r
-    auto& desktop = Desktop::getInstance();\r
-\r
-    for (int i = desktop.getNumComponents(); --i >= 0;)\r
-        if (auto* mainWindow = dynamic_cast<MainHostWindow*> (desktop.getComponent(i)))\r
-            return mainWindow;\r
-\r
-    return nullptr;\r
-}\r
-\r
-GraphDocumentComponent* FilterIOConfigurationWindow::getGraphEditor() const\r
-{\r
-    if (auto* mainWindow = getMainWindow())\r
-        return mainWindow->graphHolder.get();\r
-\r
-    return nullptr;\r
-}\r
-\r
-AudioProcessorGraph* FilterIOConfigurationWindow::getGraph() const\r
-{\r
-    if (auto* graphEditor = getGraphEditor())\r
-        if (auto* panel = graphEditor->graph.get())\r
-            return &panel->graph;\r
-\r
-    return nullptr;\r
-}\r
diff --git a/extras/AudioPluginHost/Source/FilterIOConfiguration.h b/extras/AudioPluginHost/Source/FilterIOConfiguration.h
deleted file mode 100644 (file)
index 4666ddc..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*\r
-  ==============================================================================\r
-\r
-   This file is part of the JUCE library.\r
-   Copyright (c) 2017 - ROLI Ltd.\r
-\r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
-   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
-   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
-   27th April 2017).\r
-\r
-   End User License Agreement: www.juce.com/juce-5-licence\r
-   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
-   Or: You may also use this code under the terms of the GPL v3 (see\r
-   www.gnu.org/licenses).\r
-\r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
-\r
-  ==============================================================================\r
-*/\r
-\r
-#pragma once\r
-\r
-class MainHostWindow;\r
-class GraphDocumentComponent;\r
-\r
-\r
-//==============================================================================\r
-class FilterIOConfigurationWindow   : public  AudioProcessorEditor\r
-{\r
-public:\r
-    FilterIOConfigurationWindow (AudioProcessor&);\r
-    ~FilterIOConfigurationWindow();\r
-\r
-    //==============================================================================\r
-    void paint (Graphics& g) override;\r
-    void resized() override;\r
-\r
-private:\r
-    class InputOutputConfig;\r
-\r
-    AudioProcessor::BusesLayout currentLayout;\r
-    Label title;\r
-    ScopedPointer<InputOutputConfig> inConfig, outConfig;\r
-\r
-    InputOutputConfig* getConfig (bool isInput) noexcept    { return isInput ? inConfig : outConfig; }\r
-    void update();\r
-\r
-    MainHostWindow* getMainWindow() const;\r
-    GraphDocumentComponent* getGraphEditor() const;\r
-    AudioProcessorGraph* getGraph() const;\r
-    AudioProcessorGraph::NodeID getNodeID() const;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilterIOConfigurationWindow)\r
-};\r
diff --git a/extras/AudioPluginHost/Source/Filters/FilterGraph.cpp b/extras/AudioPluginHost/Source/Filters/FilterGraph.cpp
new file mode 100644 (file)
index 0000000..c894505
--- /dev/null
@@ -0,0 +1,466 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#include "../JuceLibraryCode/JuceHeader.h"\r
+#include "../UI/MainHostWindow.h"\r
+#include "FilterGraph.h"\r
+#include "InternalFilters.h"\r
+#include "../UI/GraphEditorPanel.h"\r
+\r
+\r
+//==============================================================================\r
+FilterGraph::FilterGraph (AudioPluginFormatManager& fm)\r
+    : FileBasedDocument (getFilenameSuffix(),\r
+                         getFilenameWildcard(),\r
+                         "Load a filter graph",\r
+                         "Save a filter graph"),\r
+      formatManager (fm)\r
+{\r
+    newDocument();\r
+\r
+    graph.addListener (this);\r
+    graph.addChangeListener (this);\r
+\r
+    setChangedFlag (false);\r
+}\r
+\r
+FilterGraph::~FilterGraph()\r
+{\r
+    graph.removeListener (this);\r
+    graph.removeChangeListener (this);\r
+    graph.clear();\r
+}\r
+\r
+FilterGraph::NodeID FilterGraph::getNextUID() noexcept\r
+{\r
+    return ++lastUID;\r
+}\r
+\r
+//==============================================================================\r
+void FilterGraph::changeListenerCallback (ChangeBroadcaster*)\r
+{\r
+    changed();\r
+\r
+    for (int i = activePluginWindows.size(); --i >= 0;)\r
+        if (! graph.getNodes().contains (activePluginWindows.getUnchecked(i)->node))\r
+            activePluginWindows.remove (i);\r
+}\r
+\r
+AudioProcessorGraph::Node::Ptr FilterGraph::getNodeForName (const String& name) const\r
+{\r
+    for (auto* node : graph.getNodes())\r
+        if (auto p = node->getProcessor())\r
+            if (p->getName().equalsIgnoreCase (name))\r
+                return node;\r
+\r
+    return nullptr;\r
+}\r
+\r
+void FilterGraph::addPlugin (const PluginDescription& desc, Point<double> p)\r
+{\r
+    struct AsyncCallback : public AudioPluginFormat::InstantiationCompletionCallback\r
+    {\r
+        AsyncCallback (FilterGraph& g, Point<double> pos)  : owner (g), position (pos)\r
+        {}\r
+\r
+        void completionCallback (AudioPluginInstance* instance, const String& error) override\r
+        {\r
+            owner.addFilterCallback (instance, error, position);\r
+        }\r
+\r
+        FilterGraph& owner;\r
+        Point<double> position;\r
+    };\r
+\r
+    formatManager.createPluginInstanceAsync (desc,\r
+                                             graph.getSampleRate(),\r
+                                             graph.getBlockSize(),\r
+                                             new AsyncCallback (*this, p));\r
+}\r
+\r
+void FilterGraph::addFilterCallback (AudioPluginInstance* instance, const String& error, Point<double> pos)\r
+{\r
+    if (instance == nullptr)\r
+    {\r
+        AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,\r
+                                          TRANS("Couldn't create filter"),\r
+                                          error);\r
+    }\r
+    else\r
+    {\r
+        instance->enableAllBuses();\r
+\r
+        if (auto node = graph.addNode (instance))\r
+        {\r
+            node->properties.set ("x", pos.x);\r
+            node->properties.set ("y", pos.y);\r
+            changed();\r
+        }\r
+    }\r
+}\r
+\r
+void FilterGraph::setNodePosition (NodeID nodeID, Point<double> pos)\r
+{\r
+    if (auto* n = graph.getNodeForId (nodeID))\r
+    {\r
+        n->properties.set ("x", jlimit (0.0, 1.0, pos.x));\r
+        n->properties.set ("y", jlimit (0.0, 1.0, pos.y));\r
+    }\r
+}\r
+\r
+Point<double> FilterGraph::getNodePosition (NodeID nodeID) const\r
+{\r
+    if (auto* n = graph.getNodeForId (nodeID))\r
+        return { static_cast<double> (n->properties ["x"]),\r
+                 static_cast<double> (n->properties ["y"]) };\r
+\r
+    return {};\r
+}\r
+\r
+//==============================================================================\r
+void FilterGraph::clear()\r
+{\r
+    closeAnyOpenPluginWindows();\r
+    graph.clear();\r
+    changed();\r
+}\r
+\r
+PluginWindow* FilterGraph::getOrCreateWindowFor (AudioProcessorGraph::Node* node, PluginWindow::Type type)\r
+{\r
+    jassert (node != nullptr);\r
+\r
+   #if JUCE_IOS || JUCE_ANDROID\r
+    closeAnyOpenPluginWindows();\r
+   #else\r
+    for (auto* w : activePluginWindows)\r
+        if (w->node == node && w->type == type)\r
+            return w;\r
+   #endif\r
+\r
+    if (auto* processor = node->getProcessor())\r
+    {\r
+        if (auto* plugin = dynamic_cast<AudioPluginInstance*> (processor))\r
+        {\r
+            auto description = plugin->getPluginDescription();\r
+\r
+            if (description.pluginFormatName == "Internal")\r
+            {\r
+                getCommandManager().invokeDirectly (CommandIDs::showAudioSettings, false);\r
+                return nullptr;\r
+            }\r
+        }\r
+\r
+        return activePluginWindows.add (new PluginWindow (node, type, activePluginWindows));\r
+    }\r
+\r
+    return nullptr;\r
+}\r
+\r
+bool FilterGraph::closeAnyOpenPluginWindows()\r
+{\r
+    bool wasEmpty = activePluginWindows.isEmpty();\r
+    activePluginWindows.clear();\r
+    return ! wasEmpty;\r
+}\r
+\r
+//==============================================================================\r
+String FilterGraph::getDocumentTitle()\r
+{\r
+    if (! getFile().exists())\r
+        return "Unnamed";\r
+\r
+    return getFile().getFileNameWithoutExtension();\r
+}\r
+\r
+void FilterGraph::newDocument()\r
+{\r
+    clear();\r
+    setFile ({});\r
+\r
+    InternalPluginFormat internalFormat;\r
+\r
+    addPlugin (internalFormat.audioInDesc,  { 0.5,  0.1 });\r
+    addPlugin (internalFormat.midiInDesc,   { 0.25, 0.1 });\r
+    addPlugin (internalFormat.audioOutDesc, { 0.5,  0.9 });\r
+\r
+    setChangedFlag (false);\r
+}\r
+\r
+Result FilterGraph::loadDocument (const File& file)\r
+{\r
+    XmlDocument doc (file);\r
+    ScopedPointer<XmlElement> xml (doc.getDocumentElement());\r
+\r
+    if (xml == nullptr || ! xml->hasTagName ("FILTERGRAPH"))\r
+        return Result::fail ("Not a valid filter graph file");\r
+\r
+    restoreFromXml (*xml);\r
+    return Result::ok();\r
+}\r
+\r
+Result FilterGraph::saveDocument (const File& file)\r
+{\r
+    ScopedPointer<XmlElement> xml (createXml());\r
+\r
+    if (! xml->writeToFile (file, {}))\r
+        return Result::fail ("Couldn't write to the file");\r
+\r
+    return Result::ok();\r
+}\r
+\r
+File FilterGraph::getLastDocumentOpened()\r
+{\r
+    RecentlyOpenedFilesList recentFiles;\r
+    recentFiles.restoreFromString (getAppProperties().getUserSettings()\r
+                                        ->getValue ("recentFilterGraphFiles"));\r
+\r
+    return recentFiles.getFile (0);\r
+}\r
+\r
+void FilterGraph::setLastDocumentOpened (const File& file)\r
+{\r
+    RecentlyOpenedFilesList recentFiles;\r
+    recentFiles.restoreFromString (getAppProperties().getUserSettings()\r
+                                        ->getValue ("recentFilterGraphFiles"));\r
+\r
+    recentFiles.addFile (file);\r
+\r
+    getAppProperties().getUserSettings()\r
+        ->setValue ("recentFilterGraphFiles", recentFiles.toString());\r
+}\r
+\r
+//==============================================================================\r
+static void readBusLayoutFromXml (AudioProcessor::BusesLayout& busesLayout, AudioProcessor* plugin,\r
+                                  const XmlElement& xml, const bool isInput)\r
+{\r
+    auto& targetBuses = (isInput ? busesLayout.inputBuses\r
+                                 : busesLayout.outputBuses);\r
+    int maxNumBuses = 0;\r
+\r
+    if (auto* buses = xml.getChildByName (isInput ? "INPUTS" : "OUTPUTS"))\r
+    {\r
+        forEachXmlChildElementWithTagName (*buses, e, "BUS")\r
+        {\r
+            const int busIdx = e->getIntAttribute ("index");\r
+            maxNumBuses = jmax (maxNumBuses, busIdx + 1);\r
+\r
+            // the number of buses on busesLayout may not be in sync with the plugin after adding buses\r
+            // because adding an input bus could also add an output bus\r
+            for (int actualIdx = plugin->getBusCount (isInput) - 1; actualIdx < busIdx; ++actualIdx)\r
+                if (! plugin->addBus (isInput))\r
+                    return;\r
+\r
+            for (int actualIdx = targetBuses.size() - 1; actualIdx < busIdx; ++actualIdx)\r
+                targetBuses.add (plugin->getChannelLayoutOfBus (isInput, busIdx));\r
+\r
+            auto layout = e->getStringAttribute ("layout");\r
+\r
+            if (layout.isNotEmpty())\r
+                targetBuses.getReference (busIdx) = AudioChannelSet::fromAbbreviatedString (layout);\r
+        }\r
+    }\r
+\r
+    // if the plugin has more buses than specified in the xml, then try to remove them!\r
+    while (maxNumBuses < targetBuses.size())\r
+    {\r
+        if (! plugin->removeBus (isInput))\r
+            return;\r
+\r
+        targetBuses.removeLast();\r
+    }\r
+}\r
+\r
+//==============================================================================\r
+static XmlElement* createBusLayoutXml (const AudioProcessor::BusesLayout& layout, const bool isInput)\r
+{\r
+    auto& buses = isInput ? layout.inputBuses\r
+                          : layout.outputBuses;\r
+\r
+    auto* xml = new XmlElement (isInput ? "INPUTS" : "OUTPUTS");\r
+\r
+    for (int busIdx = 0; busIdx < buses.size(); ++busIdx)\r
+    {\r
+        auto& set = buses.getReference (busIdx);\r
+\r
+        auto* bus = xml->createNewChildElement ("BUS");\r
+        bus->setAttribute ("index", busIdx);\r
+        bus->setAttribute ("layout", set.isDisabled() ? "disabled" : set.getSpeakerArrangementAsString());\r
+    }\r
+\r
+    return xml;\r
+}\r
+\r
+static XmlElement* createNodeXml (AudioProcessorGraph::Node* const node) noexcept\r
+{\r
+    if (auto* plugin = dynamic_cast<AudioPluginInstance*> (node->getProcessor()))\r
+    {\r
+        auto e = new XmlElement ("FILTER");\r
+        e->setAttribute ("uid", (int) node->nodeID);\r
+        e->setAttribute ("x", node->properties ["x"].toString());\r
+        e->setAttribute ("y", node->properties ["y"].toString());\r
+\r
+        for (int i = 0; i < (int) PluginWindow::Type::numTypes; ++i)\r
+        {\r
+            auto type = (PluginWindow::Type) i;\r
+\r
+            if (node->properties.contains (PluginWindow::getOpenProp (type)))\r
+            {\r
+                e->setAttribute (PluginWindow::getLastXProp (type), node->properties[PluginWindow::getLastXProp (type)].toString());\r
+                e->setAttribute (PluginWindow::getLastYProp (type), node->properties[PluginWindow::getLastYProp (type)].toString());\r
+                e->setAttribute (PluginWindow::getOpenProp (type),  node->properties[PluginWindow::getOpenProp (type)].toString());\r
+            }\r
+        }\r
+\r
+        {\r
+            PluginDescription pd;\r
+            plugin->fillInPluginDescription (pd);\r
+            e->addChildElement (pd.createXml());\r
+        }\r
+\r
+        {\r
+            MemoryBlock m;\r
+            node->getProcessor()->getStateInformation (m);\r
+            e->createNewChildElement ("STATE")->addTextElement (m.toBase64Encoding());\r
+        }\r
+\r
+        auto layout = plugin->getBusesLayout();\r
+\r
+        auto layouts = e->createNewChildElement ("LAYOUT");\r
+        layouts->addChildElement (createBusLayoutXml (layout, true));\r
+        layouts->addChildElement (createBusLayoutXml (layout, false));\r
+\r
+        return e;\r
+    }\r
+\r
+    jassertfalse;\r
+    return nullptr;\r
+}\r
+\r
+void FilterGraph::createNodeFromXml (const XmlElement& xml)\r
+{\r
+    PluginDescription pd;\r
+\r
+    forEachXmlChildElement (xml, e)\r
+    {\r
+        if (pd.loadFromXml (*e))\r
+            break;\r
+    }\r
+\r
+    String errorMessage;\r
+\r
+    if (auto* instance = formatManager.createPluginInstance (pd, graph.getSampleRate(),\r
+                                                             graph.getBlockSize(), errorMessage))\r
+    {\r
+        if (auto* layoutEntity = xml.getChildByName ("LAYOUT"))\r
+        {\r
+            auto layout = instance->getBusesLayout();\r
+\r
+            readBusLayoutFromXml (layout, instance, *layoutEntity, true);\r
+            readBusLayoutFromXml (layout, instance, *layoutEntity, false);\r
+\r
+            instance->setBusesLayout (layout);\r
+        }\r
+\r
+        if (auto node = graph.addNode (instance, (NodeID) xml.getIntAttribute ("uid")))\r
+        {\r
+            if (auto* state = xml.getChildByName ("STATE"))\r
+            {\r
+                MemoryBlock m;\r
+                m.fromBase64Encoding (state->getAllSubText());\r
+\r
+                node->getProcessor()->setStateInformation (m.getData(), (int) m.getSize());\r
+            }\r
+\r
+            node->properties.set ("x", xml.getDoubleAttribute ("x"));\r
+            node->properties.set ("y", xml.getDoubleAttribute ("y"));\r
+\r
+            for (int i = 0; i < (int) PluginWindow::Type::numTypes; ++i)\r
+            {\r
+                auto type = (PluginWindow::Type) i;\r
+\r
+                if (xml.hasAttribute (PluginWindow::getOpenProp (type)))\r
+                {\r
+                    node->properties.set (PluginWindow::getLastXProp (type), xml.getIntAttribute (PluginWindow::getLastXProp (type)));\r
+                    node->properties.set (PluginWindow::getLastYProp (type), xml.getIntAttribute (PluginWindow::getLastYProp (type)));\r
+                    node->properties.set (PluginWindow::getOpenProp  (type), xml.getIntAttribute (PluginWindow::getOpenProp (type)));\r
+\r
+                    if (node->properties[PluginWindow::getOpenProp (type)])\r
+                    {\r
+                        jassert (node->getProcessor() != nullptr);\r
+\r
+                        if (auto w = getOrCreateWindowFor (node, type))\r
+                            w->toFront (true);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+XmlElement* FilterGraph::createXml() const\r
+{\r
+    auto* xml = new XmlElement ("FILTERGRAPH");\r
+\r
+    for (auto* node : graph.getNodes())\r
+        xml->addChildElement (createNodeXml (node));\r
+\r
+    for (auto& connection : graph.getConnections())\r
+    {\r
+        auto e = xml->createNewChildElement ("CONNECTION");\r
+\r
+        e->setAttribute ("srcFilter", (int) connection.source.nodeID);\r
+        e->setAttribute ("srcChannel", connection.source.channelIndex);\r
+        e->setAttribute ("dstFilter", (int) connection.destination.nodeID);\r
+        e->setAttribute ("dstChannel", connection.destination.channelIndex);\r
+    }\r
+\r
+    return xml;\r
+}\r
+\r
+void FilterGraph::restoreFromXml (const XmlElement& xml)\r
+{\r
+    clear();\r
+\r
+    forEachXmlChildElementWithTagName (xml, e, "FILTER")\r
+    {\r
+        createNodeFromXml (*e);\r
+        changed();\r
+    }\r
+\r
+    forEachXmlChildElementWithTagName (xml, e, "CONNECTION")\r
+    {\r
+        graph.addConnection ({ { (NodeID) e->getIntAttribute ("srcFilter"), e->getIntAttribute ("srcChannel") },\r
+                               { (NodeID) e->getIntAttribute ("dstFilter"), e->getIntAttribute ("dstChannel") } });\r
+    }\r
+\r
+    graph.removeIllegalConnections();\r
+}\r
+\r
+File FilterGraph::getDefaultGraphDocumentOnMobile()\r
+{\r
+    auto persistantStorageLocation = File::getSpecialLocation (File::userApplicationDataDirectory);\r
+    return persistantStorageLocation.getChildFile ("state.filtergraph");\r
+}\r
diff --git a/extras/AudioPluginHost/Source/Filters/FilterGraph.h b/extras/AudioPluginHost/Source/Filters/FilterGraph.h
new file mode 100644 (file)
index 0000000..62661b5
--- /dev/null
@@ -0,0 +1,99 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#pragma once\r
+\r
+#include "../UI/PluginWindow.h"\r
+\r
+\r
+//==============================================================================\r
+/**\r
+    A collection of filters and some connections between them.\r
+*/\r
+class FilterGraph   : public FileBasedDocument,\r
+                      public AudioProcessorListener,\r
+                      private ChangeListener\r
+{\r
+public:\r
+    //==============================================================================\r
+    FilterGraph (AudioPluginFormatManager&);\r
+    ~FilterGraph();\r
+\r
+    //==============================================================================\r
+    typedef AudioProcessorGraph::NodeID NodeID;\r
+\r
+    void addPlugin (const PluginDescription&, Point<double>);\r
+\r
+    AudioProcessorGraph::Node::Ptr getNodeForName (const String& name) const;\r
+\r
+    void setNodePosition (NodeID, Point<double>);\r
+    Point<double> getNodePosition (NodeID) const;\r
+\r
+    //==============================================================================\r
+    void clear();\r
+\r
+    PluginWindow* getOrCreateWindowFor (AudioProcessorGraph::Node*, PluginWindow::Type);\r
+    void closeCurrentlyOpenWindowsFor (AudioProcessorGraph::NodeID);\r
+    bool closeAnyOpenPluginWindows();\r
+\r
+    //==============================================================================\r
+    void audioProcessorParameterChanged (AudioProcessor*, int, float) override {}\r
+    void audioProcessorChanged (AudioProcessor*) override { changed(); }\r
+\r
+    //==============================================================================\r
+    XmlElement* createXml() const;\r
+    void restoreFromXml (const XmlElement& xml);\r
+\r
+    static const char* getFilenameSuffix()      { return ".filtergraph"; }\r
+    static const char* getFilenameWildcard()    { return "*.filtergraph"; }\r
+\r
+    //==============================================================================\r
+    void newDocument();\r
+    String getDocumentTitle() override;\r
+    Result loadDocument (const File& file) override;\r
+    Result saveDocument (const File& file) override;\r
+    File getLastDocumentOpened() override;\r
+    void setLastDocumentOpened (const File& file) override;\r
+\r
+    static File getDefaultGraphDocumentOnMobile();\r
+\r
+    //==============================================================================\r
+    AudioProcessorGraph graph;\r
+\r
+private:\r
+    //==============================================================================\r
+    AudioPluginFormatManager& formatManager;\r
+    OwnedArray<PluginWindow> activePluginWindows;\r
+\r
+    NodeID lastUID = 0;\r
+    NodeID getNextUID() noexcept;\r
+\r
+    void createNodeFromXml (const XmlElement& xml);\r
+    void addFilterCallback (AudioPluginInstance*, const String& error, Point<double>);\r
+    void changeListenerCallback (ChangeBroadcaster*) override;\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilterGraph)\r
+};\r
diff --git a/extras/AudioPluginHost/Source/Filters/FilterIOConfiguration.cpp b/extras/AudioPluginHost/Source/Filters/FilterIOConfiguration.cpp
new file mode 100644 (file)
index 0000000..3261ba9
--- /dev/null
@@ -0,0 +1,548 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#include "../JuceLibraryCode/JuceHeader.h"\r
+#include "../UI/GraphEditorPanel.h"\r
+#include "InternalFilters.h"\r
+#include "../UI/MainHostWindow.h"\r
+#include "FilterIOConfiguration.h"\r
+\r
+\r
+//==============================================================================\r
+struct NumberedBoxes  : public TableListBox,\r
+                        private TableListBoxModel,\r
+                        private Button::Listener\r
+{\r
+    struct Listener\r
+    {\r
+        virtual ~Listener() {}\r
+\r
+        virtual void addColumn()    = 0;\r
+        virtual void removeColumn() = 0;\r
+        virtual void columnSelected (int columnId) = 0;\r
+    };\r
+\r
+    enum\r
+    {\r
+        plusButtonColumnId  = 128,\r
+        minusButtonColumnId = 129\r
+    };\r
+\r
+    //==============================================================================\r
+    NumberedBoxes (Listener& listenerToUse, bool canCurrentlyAddColumn, bool canCurrentlyRemoveColumn)\r
+        : TableListBox ("NumberedBoxes", this),\r
+          listener (listenerToUse),\r
+          canAddColumn (canCurrentlyAddColumn),\r
+          canRemoveColumn (canCurrentlyRemoveColumn)\r
+    {\r
+        auto& tableHeader = getHeader();\r
+\r
+        for (int i = 0; i < 16; ++i)\r
+            tableHeader.addColumn (String (i + 1), i + 1, 40);\r
+\r
+        setHeaderHeight (0);\r
+        setRowHeight (40);\r
+        getHorizontalScrollBar().setAutoHide (false);\r
+    }\r
+\r
+    void setSelected (int columnId)\r
+    {\r
+        if (auto* button = dynamic_cast<TextButton*> (getCellComponent (columnId, 0)))\r
+            button->setToggleState (true, NotificationType::dontSendNotification);\r
+    }\r
+\r
+    void setCanAddColumn (bool canCurrentlyAdd)\r
+    {\r
+        if (canCurrentlyAdd != canAddColumn)\r
+        {\r
+            canAddColumn = canCurrentlyAdd;\r
+\r
+            if (auto* button = dynamic_cast<TextButton*> (getCellComponent (plusButtonColumnId, 0)))\r
+                button->setEnabled (true);\r
+        }\r
+    }\r
+\r
+    void setCanRemoveColumn (bool canCurrentlyRemove)\r
+    {\r
+        if (canCurrentlyRemove != canRemoveColumn)\r
+        {\r
+            canRemoveColumn = canCurrentlyRemove;\r
+\r
+            if (auto* button = dynamic_cast<TextButton*> (getCellComponent (minusButtonColumnId, 0)))\r
+                button->setEnabled (true);\r
+        }\r
+    }\r
+\r
+private:\r
+    //==============================================================================\r
+    Listener& listener;\r
+    bool canAddColumn, canRemoveColumn;\r
+\r
+    //==============================================================================\r
+    int getNumRows() override                                             { return 1; }\r
+    void paintCell (Graphics&, int, int, int, int, bool) override         {}\r
+    void paintRowBackground (Graphics& g, int, int, int, bool) override   { g.fillAll (Colours::grey); }\r
+\r
+    Component* refreshComponentForCell (int, int columnId, bool,\r
+                                        Component* existingComponentToUpdate) override\r
+    {\r
+        auto* textButton = dynamic_cast<TextButton*> (existingComponentToUpdate);\r
+\r
+        if (textButton == nullptr)\r
+            textButton = new TextButton();\r
+\r
+        textButton->setButtonText (getButtonName (columnId));\r
+        textButton->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight |\r
+                                       Button::ConnectedOnTop  | Button::ConnectedOnBottom);\r
+\r
+        const bool isPlusMinusButton = (columnId == plusButtonColumnId || columnId == minusButtonColumnId);\r
+\r
+        if (isPlusMinusButton)\r
+        {\r
+            textButton->setEnabled (columnId == plusButtonColumnId ? canAddColumn : canRemoveColumn);\r
+        }\r
+        else\r
+        {\r
+            textButton->setRadioGroupId (1, NotificationType::dontSendNotification);\r
+            textButton->setClickingTogglesState (true);\r
+\r
+            auto busColour = Colours::green.withRotatedHue (static_cast<float> (columnId) / 5.0f);\r
+            textButton->setColour (TextButton::buttonColourId, busColour);\r
+            textButton->setColour (TextButton::buttonOnColourId, busColour.withMultipliedBrightness (2.0f));\r
+        }\r
+\r
+        textButton->addListener (this);\r
+\r
+        return textButton;\r
+    }\r
+\r
+    //==============================================================================\r
+    String getButtonName (int columnId)\r
+    {\r
+        if (columnId == plusButtonColumnId)  return "+";\r
+        if (columnId == minusButtonColumnId) return "-";\r
+\r
+        return String (columnId);\r
+    }\r
+\r
+    void buttonClicked (Button* btn) override\r
+    {\r
+        auto text = btn->getButtonText();\r
+\r
+        if (text == "+") listener.addColumn();\r
+        if (text == "-") listener.removeColumn();\r
+    }\r
+\r
+    void buttonStateChanged (Button* btn) override\r
+    {\r
+        auto text = btn->getButtonText();\r
+\r
+        if (text == "+" || text == "-")\r
+            return;\r
+\r
+        if (btn->getToggleState())\r
+            listener.columnSelected (text.getIntValue());\r
+    }\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NumberedBoxes)\r
+};\r
+\r
+//==============================================================================\r
+class FilterIOConfigurationWindow::InputOutputConfig  : public Component,\r
+                                                        private ComboBox::Listener,\r
+                                                        private Button::Listener,\r
+                                                        private NumberedBoxes::Listener\r
+{\r
+public:\r
+    InputOutputConfig (FilterIOConfigurationWindow& parent, bool direction)\r
+        : owner (parent),\r
+          ioTitle ("ioLabel", direction ? "Input Configuration" : "Output Configuration"),\r
+          ioBuses (*this, false, false),\r
+          isInput (direction)\r
+    {\r
+        ioTitle.setFont (ioTitle.getFont().withStyle (Font::bold));\r
+        nameLabel.setFont (nameLabel.getFont().withStyle (Font::bold));\r
+        layoutLabel.setFont (layoutLabel.getFont().withStyle (Font::bold));\r
+        enabledToggle.setClickingTogglesState (true);\r
+\r
+        layouts.addListener (this);\r
+        enabledToggle.addListener (this);\r
+\r
+        addAndMakeVisible (layoutLabel);\r
+        addAndMakeVisible (layouts);\r
+        addAndMakeVisible (enabledToggle);\r
+        addAndMakeVisible (ioTitle);\r
+        addAndMakeVisible (nameLabel);\r
+        addAndMakeVisible (name);\r
+        addAndMakeVisible (ioBuses);\r
+\r
+        updateBusButtons();\r
+        updateBusLayout();\r
+    }\r
+\r
+    void paint (Graphics& g) override\r
+    {\r
+        g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r
+    }\r
+\r
+    void resized() override\r
+    {\r
+        auto r = getLocalBounds().reduced (10);\r
+\r
+        ioTitle.setBounds (r.removeFromTop (14));\r
+        r.reduce (10, 0);\r
+        r.removeFromTop (16);\r
+\r
+        ioBuses.setBounds (r.removeFromTop (60));\r
+\r
+        {\r
+            auto label = r.removeFromTop (24);\r
+            nameLabel.setBounds (label.removeFromLeft (100));\r
+            enabledToggle.setBounds (label.removeFromRight (80));\r
+            name.setBounds (label);\r
+        }\r
+\r
+        {\r
+            auto label = r.removeFromTop (24);\r
+            layoutLabel.setBounds (label.removeFromLeft (100));\r
+            layouts.setBounds (label);\r
+        }\r
+    }\r
+\r
+private:\r
+    void updateBusButtons()\r
+    {\r
+        if (auto* filter = owner.getAudioProcessor())\r
+        {\r
+            auto& header = ioBuses.getHeader();\r
+            header.removeAllColumns();\r
+\r
+            const int n = filter->getBusCount (isInput);\r
+\r
+            for (int i = 0; i < n; ++i)\r
+                header.addColumn ("", i + 1, 40);\r
+\r
+            header.addColumn ("+", NumberedBoxes::plusButtonColumnId,  20);\r
+            header.addColumn ("-", NumberedBoxes::minusButtonColumnId, 20);\r
+\r
+            ioBuses.setCanAddColumn    (filter->canAddBus    (isInput));\r
+            ioBuses.setCanRemoveColumn (filter->canRemoveBus (isInput));\r
+        }\r
+\r
+        ioBuses.setSelected (currentBus + 1);\r
+    }\r
+\r
+    void updateBusLayout()\r
+    {\r
+        if (auto* filter = owner.getAudioProcessor())\r
+        {\r
+            if (auto* bus = filter->getBus (isInput, currentBus))\r
+            {\r
+                name.setText (bus->getName(), NotificationType::dontSendNotification);\r
+\r
+                int i;\r
+                for (i = 1; i < AudioChannelSet::maxChannelsOfNamedLayout; ++i)\r
+                    if ((layouts.indexOfItemId(i) == -1) != bus->supportedLayoutWithChannels (i).isDisabled())\r
+                        break;\r
+\r
+                // supported layouts have changed\r
+                if (i < AudioChannelSet::maxChannelsOfNamedLayout)\r
+                {\r
+                    layouts.clear();\r
+\r
+                    for (i = 1; i < AudioChannelSet::maxChannelsOfNamedLayout; ++i)\r
+                    {\r
+                        auto set = bus->supportedLayoutWithChannels (i);\r
+\r
+                        if (! set.isDisabled())\r
+                            layouts.addItem (set.getDescription(), i);\r
+                    }\r
+                }\r
+\r
+                layouts.setSelectedId (bus->getLastEnabledLayout().size());\r
+\r
+                const bool canBeDisabled = bus->isNumberOfChannelsSupported (0);\r
+\r
+                if (canBeDisabled != enabledToggle.isEnabled())\r
+                    enabledToggle.setEnabled (canBeDisabled);\r
+\r
+                enabledToggle.setToggleState (bus->isEnabled(), NotificationType::dontSendNotification);\r
+            }\r
+        }\r
+    }\r
+\r
+    //==============================================================================\r
+    void comboBoxChanged (ComboBox* combo) override\r
+    {\r
+        if (combo == &layouts)\r
+        {\r
+            if (auto* p = owner.getAudioProcessor())\r
+            {\r
+                if (auto* bus = p->getBus (isInput, currentBus))\r
+                {\r
+                    auto selectedNumChannels = layouts.getSelectedId();\r
+\r
+                    if (selectedNumChannels != bus->getLastEnabledLayout().size())\r
+                    {\r
+                        if (isPositiveAndBelow (selectedNumChannels, AudioChannelSet::maxChannelsOfNamedLayout)\r
+                             && bus->setCurrentLayoutWithoutEnabling (bus->supportedLayoutWithChannels (selectedNumChannels)))\r
+                        {\r
+                            if (auto* config = owner.getConfig (! isInput))\r
+                                config->updateBusLayout();\r
+\r
+                            owner.update();\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    void buttonClicked (Button*) override {}\r
+\r
+    void buttonStateChanged (Button* btn) override\r
+    {\r
+        if (btn == &enabledToggle && enabledToggle.isEnabled())\r
+        {\r
+            if (auto* p = owner.getAudioProcessor())\r
+            {\r
+                if (auto* bus = p->getBus (isInput, currentBus))\r
+                {\r
+                    if (bus->isEnabled() != enabledToggle.getToggleState())\r
+                    {\r
+                        bool success = enabledToggle.getToggleState() ? bus->enable()\r
+                                                                      : bus->setCurrentLayout (AudioChannelSet::disabled());\r
+\r
+                        if (success)\r
+                        {\r
+                            updateBusLayout();\r
+\r
+                            if (auto* config = owner.getConfig (! isInput))\r
+                                config->updateBusLayout();\r
+\r
+                            owner.update();\r
+                        }\r
+                        else\r
+                        {\r
+                            enabledToggle.setToggleState (! enabledToggle.getToggleState(),\r
+                                                          NotificationType::dontSendNotification);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    //==============================================================================\r
+    void addColumn() override\r
+    {\r
+        if (auto* p = owner.getAudioProcessor())\r
+        {\r
+            if (p->canAddBus (isInput))\r
+            {\r
+                if (p->addBus (isInput))\r
+                {\r
+                    updateBusButtons();\r
+                    updateBusLayout();\r
+\r
+                    if (auto* config = owner.getConfig (! isInput))\r
+                    {\r
+                        config->updateBusButtons();\r
+                        config->updateBusLayout();\r
+                    }\r
+                }\r
+\r
+                owner.update();\r
+            }\r
+        }\r
+    }\r
+\r
+    void removeColumn() override\r
+    {\r
+        if (auto* p = owner.getAudioProcessor())\r
+        {\r
+            if (p->getBusCount (isInput) > 1 && p->canRemoveBus (isInput))\r
+            {\r
+                if (p->removeBus (isInput))\r
+                {\r
+                    currentBus = jmin (p->getBusCount (isInput) - 1, currentBus);\r
+\r
+                    updateBusButtons();\r
+                    updateBusLayout();\r
+\r
+                    if (auto* config = owner.getConfig (! isInput))\r
+                    {\r
+                        config->updateBusButtons();\r
+                        config->updateBusLayout();\r
+                    }\r
+\r
+                    owner.update();\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    void columnSelected (int columnId) override\r
+    {\r
+        const int newBus = columnId - 1;\r
+\r
+        if (currentBus != newBus)\r
+        {\r
+            currentBus = newBus;\r
+            ioBuses.setSelected (currentBus + 1);\r
+            updateBusLayout();\r
+        }\r
+    }\r
+\r
+    //==============================================================================\r
+    FilterIOConfigurationWindow& owner;\r
+    Label ioTitle, name;\r
+    Label nameLabel { "nameLabel", "Bus Name:" };\r
+    Label layoutLabel { "layoutLabel", "Channel Layout:" };\r
+    ToggleButton enabledToggle { "Enabled" };\r
+    ComboBox layouts;\r
+    NumberedBoxes ioBuses;\r
+    bool isInput;\r
+    int currentBus = 0;\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InputOutputConfig)\r
+};\r
+\r
+\r
+FilterIOConfigurationWindow::FilterIOConfigurationWindow (AudioProcessor& p)\r
+   : AudioProcessorEditor (&p),\r
+     title ("title", p.getName())\r
+{\r
+    setOpaque (true);\r
+\r
+    title.setFont (title.getFont().withStyle (Font::bold));\r
+    addAndMakeVisible (title);\r
+\r
+    {\r
+        ScopedLock renderLock (p.getCallbackLock());\r
+        p.suspendProcessing (true);\r
+        p.releaseResources();\r
+    }\r
+\r
+    if (p.getBusCount (true)  > 0 || p.canAddBus (true))\r
+        addAndMakeVisible (inConfig = new InputOutputConfig (*this, true));\r
+\r
+    if (p.getBusCount (false) > 0 || p.canAddBus (false))\r
+        addAndMakeVisible (outConfig = new InputOutputConfig (*this, false));\r
+\r
+    currentLayout = p.getBusesLayout();\r
+    setSize (400, (inConfig != nullptr && outConfig != nullptr ? 160 : 0) + 200);\r
+}\r
+\r
+FilterIOConfigurationWindow::~FilterIOConfigurationWindow()\r
+{\r
+    if (auto* graph = getGraph())\r
+    {\r
+        if (auto* p = getAudioProcessor())\r
+        {\r
+            ScopedLock renderLock (graph->getCallbackLock());\r
+\r
+            graph->suspendProcessing (true);\r
+            graph->releaseResources();\r
+\r
+            p->prepareToPlay (graph->getSampleRate(), graph->getBlockSize());\r
+            p->suspendProcessing (false);\r
+\r
+            graph->prepareToPlay (graph->getSampleRate(), graph->getBlockSize());\r
+            graph->suspendProcessing (false);\r
+        }\r
+    }\r
+}\r
+\r
+void FilterIOConfigurationWindow::paint (Graphics& g)\r
+{\r
+     g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r
+}\r
+\r
+void FilterIOConfigurationWindow::resized()\r
+{\r
+    auto r = getLocalBounds().reduced (10);\r
+\r
+    title.setBounds (r.removeFromTop (14));\r
+    r.reduce (10, 0);\r
+\r
+    if (inConfig != nullptr)\r
+        inConfig->setBounds (r.removeFromTop (160));\r
+\r
+    if (outConfig != nullptr)\r
+        outConfig->setBounds (r.removeFromTop (160));\r
+}\r
+\r
+void FilterIOConfigurationWindow::update()\r
+{\r
+    auto nodeID = getNodeID();\r
+\r
+    if (auto* graph = getGraph())\r
+        if (nodeID != 0)\r
+            graph->disconnectNode (nodeID);\r
+\r
+    if (auto* graphEditor = getGraphEditor())\r
+        if (auto* panel = graphEditor->graphPanel.get())\r
+            panel->updateComponents();\r
+}\r
+\r
+AudioProcessorGraph::NodeID FilterIOConfigurationWindow::getNodeID() const\r
+{\r
+    if (auto* graph = getGraph())\r
+        for (auto* node : graph->getNodes())\r
+            if (node->getProcessor() == getAudioProcessor())\r
+                return node->nodeID;\r
+\r
+    return 0;\r
+}\r
+\r
+MainHostWindow* FilterIOConfigurationWindow::getMainWindow() const\r
+{\r
+    auto& desktop = Desktop::getInstance();\r
+\r
+    for (int i = desktop.getNumComponents(); --i >= 0;)\r
+        if (auto* mainWindow = dynamic_cast<MainHostWindow*> (desktop.getComponent(i)))\r
+            return mainWindow;\r
+\r
+    return nullptr;\r
+}\r
+\r
+GraphDocumentComponent* FilterIOConfigurationWindow::getGraphEditor() const\r
+{\r
+    if (auto* mainWindow = getMainWindow())\r
+        return mainWindow->graphHolder.get();\r
+\r
+    return nullptr;\r
+}\r
+\r
+AudioProcessorGraph* FilterIOConfigurationWindow::getGraph() const\r
+{\r
+    if (auto* graphEditor = getGraphEditor())\r
+        if (auto* panel = graphEditor->graph.get())\r
+            return &panel->graph;\r
+\r
+    return nullptr;\r
+}\r
diff --git a/extras/AudioPluginHost/Source/Filters/FilterIOConfiguration.h b/extras/AudioPluginHost/Source/Filters/FilterIOConfiguration.h
new file mode 100644 (file)
index 0000000..4666ddc
--- /dev/null
@@ -0,0 +1,60 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#pragma once\r
+\r
+class MainHostWindow;\r
+class GraphDocumentComponent;\r
+\r
+\r
+//==============================================================================\r
+class FilterIOConfigurationWindow   : public  AudioProcessorEditor\r
+{\r
+public:\r
+    FilterIOConfigurationWindow (AudioProcessor&);\r
+    ~FilterIOConfigurationWindow();\r
+\r
+    //==============================================================================\r
+    void paint (Graphics& g) override;\r
+    void resized() override;\r
+\r
+private:\r
+    class InputOutputConfig;\r
+\r
+    AudioProcessor::BusesLayout currentLayout;\r
+    Label title;\r
+    ScopedPointer<InputOutputConfig> inConfig, outConfig;\r
+\r
+    InputOutputConfig* getConfig (bool isInput) noexcept    { return isInput ? inConfig : outConfig; }\r
+    void update();\r
+\r
+    MainHostWindow* getMainWindow() const;\r
+    GraphDocumentComponent* getGraphEditor() const;\r
+    AudioProcessorGraph* getGraph() const;\r
+    AudioProcessorGraph::NodeID getNodeID() const;\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilterIOConfigurationWindow)\r
+};\r
diff --git a/extras/AudioPluginHost/Source/Filters/InternalFilters.cpp b/extras/AudioPluginHost/Source/Filters/InternalFilters.cpp
new file mode 100644 (file)
index 0000000..0b1f2c8
--- /dev/null
@@ -0,0 +1,399 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#include "../JuceLibraryCode/JuceHeader.h"\r
+#include "InternalFilters.h"\r
+#include "FilterGraph.h"\r
+\r
+//==============================================================================\r
+class InternalPlugin   : public AudioPluginInstance\r
+{\r
+protected:\r
+    InternalPlugin (const PluginDescription& descr,\r
+                    const AudioChannelSet& channelSetToUse = AudioChannelSet::stereo())\r
+        : AudioPluginInstance (getBusProperties (descr.numInputChannels == 0, channelSetToUse)),\r
+          name  (descr.fileOrIdentifier.upToFirstOccurrenceOf (":", false, false)),\r
+          state (descr.fileOrIdentifier.fromFirstOccurrenceOf (":", false, false)),\r
+          isGenerator (descr.numInputChannels == 0),\r
+          hasMidi (descr.isInstrument),\r
+          channelSet (channelSetToUse)\r
+    {\r
+        jassert (channelSetToUse.size() == descr.numOutputChannels);\r
+    }\r
+\r
+public:\r
+    //==============================================================================\r
+    const String getName() const override                     { return name; }\r
+    double getTailLengthSeconds() const override              { return 0.0; }\r
+    bool acceptsMidi() const override                         { return hasMidi; }\r
+    bool producesMidi() const override                        { return hasMidi; }\r
+    AudioProcessorEditor* createEditor() override             { return nullptr; }\r
+    bool hasEditor() const override                           { return false; }\r
+    int getNumPrograms() override                             { return 0; }\r
+    int getCurrentProgram() override                          { return 0; }\r
+    void setCurrentProgram (int) override                     {}\r
+    const String getProgramName (int) override                { return {}; }\r
+    void changeProgramName (int, const String&) override      {}\r
+    void getStateInformation (juce::MemoryBlock&) override    {}\r
+    void setStateInformation (const void*, int) override      {}\r
+\r
+    //==============================================================================\r
+    bool isBusesLayoutSupported (const BusesLayout& layout) const override\r
+    {\r
+        if (! isGenerator)\r
+        {\r
+            if (layout.getMainOutputChannelSet() != channelSet)\r
+                return false;\r
+        }\r
+\r
+        if (layout.getMainInputChannelSet() != channelSet)\r
+            return false;\r
+\r
+        return true;\r
+    }\r
+\r
+    //==============================================================================\r
+    void fillInPluginDescription (PluginDescription& description) const override\r
+    {\r
+        description = getPluginDescription (name + ":" + state,\r
+                                            isGenerator,\r
+                                            hasMidi,\r
+                                            channelSet);\r
+    }\r
+\r
+    static PluginDescription getPluginDescription (const String& identifier,\r
+                                                   bool registerAsGenerator,\r
+                                                   bool acceptsMidi,\r
+                                                   const AudioChannelSet& channelSetToUse\r
+                                                      = AudioChannelSet::stereo())\r
+    {\r
+        PluginDescription descr;\r
+        auto pluginName  = identifier.upToFirstOccurrenceOf (":", false, false);\r
+        auto pluginState = identifier.fromFirstOccurrenceOf (":", false, false);\r
+\r
+        descr.name              = pluginName;\r
+        descr.descriptiveName   = pluginName;\r
+        descr.pluginFormatName  = "Internal";\r
+        descr.category          = (registerAsGenerator ? (acceptsMidi ? "Synth" : "Generator") : "Effect");\r
+        descr.manufacturerName  = "ROLI Ltd.";\r
+        descr.version           = ProjectInfo::versionString;\r
+        descr.fileOrIdentifier  = pluginName + ":" + pluginState;\r
+        descr.uid               = pluginName.hashCode();\r
+        descr.isInstrument      = (acceptsMidi && registerAsGenerator);\r
+        descr.numInputChannels  = (registerAsGenerator ? 0 : channelSetToUse.size());\r
+        descr.numOutputChannels = channelSetToUse.size();\r
+\r
+        return descr;\r
+    }\r
+private:\r
+    static BusesProperties getBusProperties (bool registerAsGenerator,\r
+                                             const AudioChannelSet& channelSetToUse)\r
+    {\r
+        return registerAsGenerator ? BusesProperties().withOutput ("Output", channelSetToUse)\r
+                                   : BusesProperties().withInput  ("Input",  channelSetToUse)\r
+                                                      .withOutput ("Output", channelSetToUse);\r
+    }\r
+\r
+    //==============================================================================\r
+    String name, state;\r
+    bool isGenerator, hasMidi;\r
+    AudioChannelSet channelSet;\r
+\r
+    //==============================================================================\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InternalPlugin)\r
+};\r
+\r
+//==============================================================================\r
+class SineWaveSynth :   public InternalPlugin\r
+{\r
+public:\r
+    SineWaveSynth (const PluginDescription& descr) :   InternalPlugin (descr)\r
+    {\r
+        const int numVoices = 8;\r
+\r
+        // Add some voices...\r
+        for (int i = numVoices; --i >= 0;)\r
+            synth.addVoice (new SineWaveVoice());\r
+\r
+        // ..and give the synth a sound to play\r
+        synth.addSound (new SineWaveSound());\r
+    }\r
+\r
+    static String getIdentifier()\r
+    {\r
+        return "Sine Wave Synth";\r
+    }\r
+\r
+    static PluginDescription getPluginDescription()\r
+    {\r
+        return InternalPlugin::getPluginDescription (getIdentifier(), true, true);\r
+    }\r
+\r
+    //==============================================================================\r
+    void prepareToPlay (double newSampleRate, int) override\r
+    {\r
+        synth.setCurrentPlaybackSampleRate (newSampleRate);\r
+    }\r
+\r
+    void releaseResources() override {}\r
+\r
+    //==============================================================================\r
+    void processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages) override\r
+    {\r
+        const int numSamples = buffer.getNumSamples();\r
+\r
+        buffer.clear();\r
+        synth.renderNextBlock (buffer, midiMessages, 0, numSamples);\r
+        buffer.applyGain (0.8f);\r
+    }\r
+\r
+private:\r
+    //==============================================================================\r
+    class SineWaveSound : public SynthesiserSound\r
+    {\r
+    public:\r
+        SineWaveSound() {}\r
+\r
+        bool appliesToNote (int /*midiNoteNumber*/) override    { return true; }\r
+        bool appliesToChannel (int /*midiChannel*/) override    { return true; }\r
+    };\r
+\r
+    class SineWaveVoice   : public SynthesiserVoice\r
+    {\r
+    public:\r
+        SineWaveVoice()\r
+        : currentAngle (0), angleDelta (0), level (0), tailOff (0)\r
+        {\r
+        }\r
+\r
+        bool canPlaySound (SynthesiserSound* sound) override\r
+        {\r
+            return dynamic_cast<SineWaveSound*> (sound) != nullptr;\r
+        }\r
+\r
+        void startNote (int midiNoteNumber, float velocity,\r
+                        SynthesiserSound* /*sound*/,\r
+                        int /*currentPitchWheelPosition*/) override\r
+        {\r
+            currentAngle = 0.0;\r
+            level = velocity * 0.15;\r
+            tailOff = 0.0;\r
+\r
+            double cyclesPerSecond = MidiMessage::getMidiNoteInHertz (midiNoteNumber);\r
+            double cyclesPerSample = cyclesPerSecond / getSampleRate();\r
+\r
+            angleDelta = cyclesPerSample * 2.0 * double_Pi;\r
+        }\r
+\r
+        void stopNote (float /*velocity*/, bool allowTailOff) override\r
+        {\r
+            if (allowTailOff)\r
+            {\r
+                // start a tail-off by setting this flag. The render callback will pick up on\r
+                // this and do a fade out, calling clearCurrentNote() when it's finished.\r
+\r
+                if (tailOff == 0.0) // we only need to begin a tail-off if it's not already doing so - the\r
+                    // stopNote method could be called more than once.\r
+                    tailOff = 1.0;\r
+            }\r
+            else\r
+            {\r
+                // we're being told to stop playing immediately, so reset everything..\r
+\r
+                clearCurrentNote();\r
+                angleDelta = 0.0;\r
+            }\r
+        }\r
+\r
+        void pitchWheelMoved (int /*newValue*/) override\r
+        {\r
+            // not implemented for the purposes of this demo!\r
+        }\r
+\r
+        void controllerMoved (int /*controllerNumber*/, int /*newValue*/) override\r
+        {\r
+            // not implemented for the purposes of this demo!\r
+        }\r
+\r
+        void renderNextBlock (AudioBuffer<float>& outputBuffer, int startSample, int numSamples) override\r
+        {\r
+            if (angleDelta != 0.0)\r
+            {\r
+                if (tailOff > 0)\r
+                {\r
+                    while (--numSamples >= 0)\r
+                    {\r
+                        const float currentSample = (float) (sin (currentAngle) * level * tailOff);\r
+\r
+                        for (int i = outputBuffer.getNumChannels(); --i >= 0;)\r
+                            outputBuffer.addSample (i, startSample, currentSample);\r
+\r
+                        currentAngle += angleDelta;\r
+                        ++startSample;\r
+\r
+                        tailOff *= 0.99;\r
+\r
+                        if (tailOff <= 0.005)\r
+                        {\r
+                            // tells the synth that this voice has stopped\r
+                            clearCurrentNote();\r
+\r
+                            angleDelta = 0.0;\r
+                            break;\r
+                        }\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    while (--numSamples >= 0)\r
+                    {\r
+                        const float currentSample = (float) (sin (currentAngle) * level);\r
+\r
+                        for (int i = outputBuffer.getNumChannels(); --i >= 0;)\r
+                            outputBuffer.addSample (i, startSample, currentSample);\r
+\r
+                        currentAngle += angleDelta;\r
+                        ++startSample;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+    private:\r
+        double currentAngle, angleDelta, level, tailOff;\r
+    };\r
+\r
+    //==============================================================================\r
+    Synthesiser synth;\r
+\r
+    //==============================================================================\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SineWaveSynth)\r
+};\r
+\r
+//==============================================================================\r
+class ReverbFilter    : public InternalPlugin\r
+{\r
+public:\r
+    ReverbFilter (const PluginDescription& descr) :   InternalPlugin (descr)\r
+    {}\r
+\r
+    static String getIdentifier()\r
+    {\r
+        return "Reverb";\r
+    }\r
+\r
+    static PluginDescription getPluginDescription()\r
+    {\r
+        return InternalPlugin::getPluginDescription (getIdentifier(), false, false);\r
+    }\r
+\r
+    void prepareToPlay (double newSampleRate, int) override\r
+    {\r
+        reverb.setSampleRate (newSampleRate);\r
+    }\r
+\r
+    void reset() override\r
+    {\r
+        reverb.reset();\r
+    }\r
+\r
+    void releaseResources() override {}\r
+\r
+    void processBlock (AudioBuffer<float>& buffer, MidiBuffer&) override\r
+    {\r
+        auto numChannels = buffer.getNumChannels();\r
+\r
+        if (numChannels == 1)\r
+            reverb.processMono (buffer.getWritePointer (0), buffer.getNumSamples());\r
+        else\r
+            reverb.processStereo (buffer.getWritePointer (0),\r
+                                  buffer.getWritePointer (1),\r
+                                  buffer.getNumSamples());\r
+\r
+        for (int ch = 2; ch < numChannels; ++ch)\r
+            buffer.clear (ch, 0, buffer.getNumSamples());\r
+    }\r
+\r
+private:\r
+    Reverb reverb;\r
+};\r
+\r
+//==============================================================================\r
+InternalPluginFormat::InternalPluginFormat()\r
+{\r
+    {\r
+        AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);\r
+        p.fillInPluginDescription (audioOutDesc);\r
+    }\r
+\r
+    {\r
+        AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode);\r
+        p.fillInPluginDescription (audioInDesc);\r
+    }\r
+\r
+    {\r
+        AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode);\r
+        p.fillInPluginDescription (midiInDesc);\r
+    }\r
+}\r
+\r
+AudioPluginInstance* InternalPluginFormat::createInstance (const String& name)\r
+{\r
+    if (name == audioOutDesc.name) return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);\r
+    if (name == audioInDesc.name)  return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode);\r
+    if (name == midiInDesc.name)   return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode);\r
+\r
+\r
+    if (name == SineWaveSynth::getIdentifier()) return new SineWaveSynth (SineWaveSynth::getPluginDescription());\r
+    if (name == ReverbFilter::getIdentifier())  return new ReverbFilter  (ReverbFilter::getPluginDescription());\r
+\r
+    return nullptr;\r
+}\r
+\r
+void InternalPluginFormat::createPluginInstance (const PluginDescription& desc,\r
+                                                 double /*initialSampleRate*/,\r
+                                                 int /*initialBufferSize*/,\r
+                                                 void* userData,\r
+                                                 void (*callback) (void*, AudioPluginInstance*, const String&))\r
+{\r
+    auto* p = createInstance (desc.name);\r
+\r
+    callback (userData, p, p == nullptr ? NEEDS_TRANS ("Invalid internal filter name") : String());\r
+}\r
+\r
+bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept\r
+{\r
+    return false;\r
+}\r
+\r
+void InternalPluginFormat::getAllTypes (OwnedArray<PluginDescription>& results)\r
+{\r
+    results.add (new PluginDescription (audioInDesc));\r
+    results.add (new PluginDescription (audioOutDesc));\r
+    results.add (new PluginDescription (midiInDesc));\r
+    results.add (new PluginDescription (SineWaveSynth::getPluginDescription()));\r
+    results.add (new PluginDescription (ReverbFilter::getPluginDescription()));\r
+}\r
diff --git a/extras/AudioPluginHost/Source/Filters/InternalFilters.h b/extras/AudioPluginHost/Source/Filters/InternalFilters.h
new file mode 100644 (file)
index 0000000..cdcde6d
--- /dev/null
@@ -0,0 +1,66 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#pragma once\r
+\r
+#include "FilterGraph.h"\r
+\r
+\r
+//==============================================================================\r
+/**\r
+    Manages the internal plugin types.\r
+*/\r
+class InternalPluginFormat   : public AudioPluginFormat\r
+{\r
+public:\r
+    //==============================================================================\r
+    InternalPluginFormat();\r
+    ~InternalPluginFormat() {}\r
+\r
+    //==============================================================================\r
+    PluginDescription audioInDesc, audioOutDesc, midiInDesc;\r
+\r
+    void getAllTypes (OwnedArray<PluginDescription>&);\r
+\r
+    //==============================================================================\r
+    String getName() const override                                                     { return "Internal"; }\r
+    bool fileMightContainThisPluginType (const String&) override                        { return true; }\r
+    FileSearchPath getDefaultLocationsToSearch() override                               { return {}; }\r
+    bool canScanForPlugins() const override                                             { return false; }\r
+    void findAllTypesForFile (OwnedArray <PluginDescription>&, const String&) override  {}\r
+    bool doesPluginStillExist (const PluginDescription&) override                       { return true; }\r
+    String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override      { return fileOrIdentifier; }\r
+    bool pluginNeedsRescanning (const PluginDescription&) override                      { return false; }\r
+    StringArray searchPathsForPlugins (const FileSearchPath&, bool, bool) override      { return {}; }\r
+\r
+private:\r
+    //==============================================================================\r
+    void createPluginInstance (const PluginDescription&, double initialSampleRate, int initialBufferSize,\r
+                               void* userData, void (*callback) (void*, AudioPluginInstance*, const String&)) override;\r
+    AudioPluginInstance* createInstance (const String& name);\r
+\r
+    bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override;\r
+};\r
diff --git a/extras/AudioPluginHost/Source/GraphEditorPanel.cpp b/extras/AudioPluginHost/Source/GraphEditorPanel.cpp
deleted file mode 100644 (file)
index 40cf310..0000000
+++ /dev/null
@@ -1,866 +0,0 @@
-/*\r
-  ==============================================================================\r
-\r
-   This file is part of the JUCE library.\r
-   Copyright (c) 2017 - ROLI Ltd.\r
-\r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
-   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
-   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
-   27th April 2017).\r
-\r
-   End User License Agreement: www.juce.com/juce-5-licence\r
-   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
-   Or: You may also use this code under the terms of the GPL v3 (see\r
-   www.gnu.org/licenses).\r
-\r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
-\r
-  ==============================================================================\r
-*/\r
-\r
-#include "../JuceLibraryCode/JuceHeader.h"\r
-#include "GraphEditorPanel.h"\r
-#include "InternalFilters.h"\r
-#include "MainHostWindow.h"\r
-\r
-\r
-//==============================================================================\r
-struct GraphEditorPanel::PinComponent   : public Component,\r
-                                          public SettableTooltipClient\r
-{\r
-    PinComponent (GraphEditorPanel& p, AudioProcessorGraph::NodeAndChannel pinToUse, bool isIn)\r
-        : panel (p), graph (p.graph), pin (pinToUse), isInput (isIn)\r
-    {\r
-        if (auto node = graph.graph.getNodeForId (pin.nodeID))\r
-        {\r
-            String tip;\r
-\r
-            if (pin.isMIDI())\r
-            {\r
-                tip = isInput ? "MIDI Input"\r
-                              : "MIDI Output";\r
-            }\r
-            else\r
-            {\r
-                auto& processor = *node->getProcessor();\r
-                auto channel = processor.getOffsetInBusBufferForAbsoluteChannelIndex (isInput, pin.channelIndex, busIdx);\r
-\r
-                if (auto* bus = processor.getBus (isInput, busIdx))\r
-                    tip = bus->getName() + ": " + AudioChannelSet::getAbbreviatedChannelTypeName (bus->getCurrentLayout().getTypeOfChannel (channel));\r
-                else\r
-                    tip = (isInput ? "Main Input: "\r
-                                   : "Main Output: ") + String (pin.channelIndex + 1);\r
-\r
-            }\r
-\r
-            setTooltip (tip);\r
-        }\r
-\r
-        setSize (16, 16);\r
-    }\r
-\r
-    void paint (Graphics& g) override\r
-    {\r
-        auto w = (float) getWidth();\r
-        auto h = (float) getHeight();\r
-\r
-        Path p;\r
-        p.addEllipse (w * 0.25f, h * 0.25f, w * 0.5f, h * 0.5f);\r
-        p.addRectangle (w * 0.4f, isInput ? (0.5f * h) : 0.0f, w * 0.2f, h * 0.5f);\r
-\r
-        auto colour = (pin.isMIDI() ? Colours::red : Colours::green);\r
-\r
-        g.setColour (colour.withRotatedHue (busIdx / 5.0f));\r
-        g.fillPath (p);\r
-    }\r
-\r
-    void mouseDown (const MouseEvent& e) override\r
-    {\r
-        AudioProcessorGraph::NodeAndChannel dummy { 0, 0 };\r
-\r
-        panel.beginConnectorDrag (isInput ? dummy : pin,\r
-                                  isInput ? pin : dummy,\r
-                                  e);\r
-    }\r
-\r
-    void mouseDrag (const MouseEvent& e) override\r
-    {\r
-        panel.dragConnector (e);\r
-    }\r
-\r
-    void mouseUp (const MouseEvent& e) override\r
-    {\r
-        panel.endDraggingConnector (e);\r
-    }\r
-\r
-    GraphEditorPanel& panel;\r
-    FilterGraph& graph;\r
-    AudioProcessorGraph::NodeAndChannel pin;\r
-    const bool isInput;\r
-    int busIdx = 0;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PinComponent)\r
-};\r
-\r
-//==============================================================================\r
-struct GraphEditorPanel::FilterComponent   : public Component\r
-{\r
-    FilterComponent (GraphEditorPanel& p, uint32 id)  : panel (p), graph (p.graph), pluginID (id)\r
-    {\r
-        shadow.setShadowProperties (DropShadow (Colours::black.withAlpha (0.5f), 3, { 0, 1 }));\r
-        setComponentEffect (&shadow);\r
-\r
-        setSize (150, 60);\r
-    }\r
-\r
-    FilterComponent (const FilterComponent&) = delete;\r
-    FilterComponent& operator= (const FilterComponent&) = delete;\r
-\r
-    void mouseDown (const MouseEvent& e) override\r
-    {\r
-        originalPos = localPointToGlobal (Point<int>());\r
-\r
-        toFront (true);\r
-\r
-        if (e.mods.isPopupMenu())\r
-            showPopupMenu();\r
-    }\r
-\r
-    void mouseDrag (const MouseEvent& e) override\r
-    {\r
-        if (! e.mods.isPopupMenu())\r
-        {\r
-            auto pos = originalPos + e.getOffsetFromDragStart();\r
-\r
-            if (getParentComponent() != nullptr)\r
-                pos = getParentComponent()->getLocalPoint (nullptr, pos);\r
-\r
-            pos += getLocalBounds().getCentre();\r
-\r
-            graph.setNodePosition (pluginID,\r
-                                   { pos.x / (double) getParentWidth(),\r
-                                     pos.y / (double) getParentHeight() });\r
-\r
-            panel.updateComponents();\r
-        }\r
-    }\r
-\r
-    void mouseUp (const MouseEvent& e) override\r
-    {\r
-        if (e.mouseWasDraggedSinceMouseDown())\r
-        {\r
-            graph.setChangedFlag (true);\r
-        }\r
-        else if (e.getNumberOfClicks() == 2)\r
-        {\r
-            if (auto f = graph.graph.getNodeForId (pluginID))\r
-                if (auto* w = graph.getOrCreateWindowFor (f, PluginWindow::Type::normal))\r
-                    w->toFront (true);\r
-        }\r
-    }\r
-\r
-    bool hitTest (int x, int y) override\r
-    {\r
-        for (auto* child : getChildren())\r
-            if (child->getBounds().contains (x, y))\r
-                return true;\r
-\r
-        return x >= 3 && x < getWidth() - 6 && y >= pinSize && y < getHeight() - pinSize;\r
-    }\r
-\r
-    void paint (Graphics& g) override\r
-    {\r
-        auto boxArea = getLocalBounds().reduced (4, pinSize);\r
-\r
-        g.setColour (findColour (TextEditor::backgroundColourId));\r
-        g.fillRect (boxArea.toFloat());\r
-\r
-        g.setColour (findColour (TextEditor::textColourId));\r
-        g.setFont (font);\r
-        g.drawFittedText (getName(), boxArea, Justification::centred, 2);\r
-    }\r
-\r
-    void resized() override\r
-    {\r
-        if (auto f = graph.graph.getNodeForId (pluginID))\r
-        {\r
-            if (auto* processor = f->getProcessor())\r
-            {\r
-                for (auto* pin : pins)\r
-                {\r
-                    const bool isInput = pin->isInput;\r
-                    auto channelIndex = pin->pin.channelIndex;\r
-                    int busIdx = 0;\r
-                    processor->getOffsetInBusBufferForAbsoluteChannelIndex (isInput, channelIndex, busIdx);\r
-\r
-                    const int total = isInput ? numIns : numOuts;\r
-                    const int index = pin->pin.isMIDI() ? (total - 1) : channelIndex;\r
-\r
-                    auto totalSpaces = static_cast<float> (total) + (static_cast<float> (jmax (0, processor->getBusCount (isInput) - 1)) * 0.5f);\r
-                    auto indexPos = static_cast<float> (index) + (static_cast<float> (busIdx) * 0.5f);\r
-\r
-                    pin->setBounds (proportionOfWidth ((1.0f + indexPos) / (totalSpaces + 1.0f)) - pinSize / 2,\r
-                                    pin->isInput ? 0 : (getHeight() - pinSize),\r
-                                    pinSize, pinSize);\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    Point<float> getPinPos (int index, bool isInput) const\r
-    {\r
-        for (auto* pin : pins)\r
-            if (pin->pin.channelIndex == index && isInput == pin->isInput)\r
-                return getPosition().toFloat() + pin->getBounds().getCentre().toFloat();\r
-\r
-        return {};\r
-    }\r
-\r
-    void update()\r
-    {\r
-        const AudioProcessorGraph::Node::Ptr f (graph.graph.getNodeForId (pluginID));\r
-        jassert (f != nullptr);\r
-\r
-        numIns = f->getProcessor()->getTotalNumInputChannels();\r
-        if (f->getProcessor()->acceptsMidi())\r
-            ++numIns;\r
-\r
-        numOuts = f->getProcessor()->getTotalNumOutputChannels();\r
-        if (f->getProcessor()->producesMidi())\r
-            ++numOuts;\r
-\r
-        int w = 100;\r
-        int h = 60;\r
-\r
-        w = jmax (w, (jmax (numIns, numOuts) + 1) * 20);\r
-\r
-        const int textWidth = font.getStringWidth (f->getProcessor()->getName());\r
-        w = jmax (w, 16 + jmin (textWidth, 300));\r
-        if (textWidth > 300)\r
-            h = 100;\r
-\r
-        setSize (w, h);\r
-\r
-        setName (f->getProcessor()->getName());\r
-\r
-        {\r
-            auto p = graph.getNodePosition (pluginID);\r
-            setCentreRelative ((float) p.x, (float) p.y);\r
-        }\r
-\r
-        if (numIns != numInputs || numOuts != numOutputs)\r
-        {\r
-            numInputs = numIns;\r
-            numOutputs = numOuts;\r
-\r
-            pins.clear();\r
-\r
-            for (int i = 0; i < f->getProcessor()->getTotalNumInputChannels(); ++i)\r
-                addAndMakeVisible (pins.add (new PinComponent (panel, { pluginID, i }, true)));\r
-\r
-            if (f->getProcessor()->acceptsMidi())\r
-                addAndMakeVisible (pins.add (new PinComponent (panel, { pluginID, AudioProcessorGraph::midiChannelIndex }, true)));\r
-\r
-            for (int i = 0; i < f->getProcessor()->getTotalNumOutputChannels(); ++i)\r
-                addAndMakeVisible (pins.add (new PinComponent (panel, { pluginID, i }, false)));\r
-\r
-            if (f->getProcessor()->producesMidi())\r
-                addAndMakeVisible (pins.add (new PinComponent (panel, { pluginID, AudioProcessorGraph::midiChannelIndex }, false)));\r
-\r
-            resized();\r
-        }\r
-    }\r
-\r
-    AudioProcessor* getProcessor() const\r
-    {\r
-        if (auto node = graph.graph.getNodeForId (pluginID))\r
-            return node->getProcessor();\r
-\r
-        return {};\r
-    }\r
-\r
-    void showPopupMenu()\r
-    {\r
-        PopupMenu m;\r
-        m.addItem (1, "Delete this filter");\r
-        m.addItem (2, "Disconnect all pins");\r
-        m.addSeparator();\r
-        m.addItem (10, "Show plugin GUI");\r
-        m.addItem (11, "Show all programs");\r
-        m.addItem (12, "Show all parameters");\r
-        m.addSeparator();\r
-        m.addItem (20, "Configure Audio I/O");\r
-        m.addItem (21, "Test state save/load");\r
-\r
-        switch (m.show())\r
-        {\r
-            case 1:   graph.graph.removeNode (pluginID); break;\r
-            case 2:   graph.graph.disconnectNode (pluginID); break;\r
-            case 10:  showWindow (PluginWindow::Type::normal); break;\r
-            case 11:  showWindow (PluginWindow::Type::programs); break;\r
-            case 12:  showWindow (PluginWindow::Type::generic); break;\r
-            case 20:  showWindow (PluginWindow::Type::audioIO); break;\r
-            case 21:  testStateSaveLoad(); break;\r
-            default:  break;\r
-        }\r
-    }\r
-\r
-    void testStateSaveLoad()\r
-    {\r
-        if (auto* processor = getProcessor())\r
-        {\r
-            MemoryBlock state;\r
-            processor->getStateInformation (state);\r
-            processor->setStateInformation (state.getData(), (int) state.getSize());\r
-        }\r
-    }\r
-\r
-    void showWindow (PluginWindow::Type type)\r
-    {\r
-        if (auto node = graph.graph.getNodeForId (pluginID))\r
-            if (auto* w = graph.getOrCreateWindowFor (node, type))\r
-                w->toFront (true);\r
-    }\r
-\r
-    GraphEditorPanel& panel;\r
-    FilterGraph& graph;\r
-    const AudioProcessorGraph::NodeID pluginID;\r
-    OwnedArray<PinComponent> pins;\r
-    int numInputs = 0, numOutputs = 0;\r
-    int pinSize = 16;\r
-    Point<int> originalPos;\r
-    Font font { 13.0f, Font::bold };\r
-    int numIns = 0, numOuts = 0;\r
-    DropShadowEffect shadow;\r
-};\r
-\r
-\r
-//==============================================================================\r
-struct GraphEditorPanel::ConnectorComponent   : public Component,\r
-                                                public SettableTooltipClient\r
-{\r
-    ConnectorComponent (GraphEditorPanel& p) : panel (p), graph (p.graph)\r
-    {\r
-        setAlwaysOnTop (true);\r
-    }\r
-\r
-    void setInput (AudioProcessorGraph::NodeAndChannel newSource)\r
-    {\r
-        if (connection.source != newSource)\r
-        {\r
-            connection.source = newSource;\r
-            update();\r
-        }\r
-    }\r
-\r
-    void setOutput (AudioProcessorGraph::NodeAndChannel newDest)\r
-    {\r
-        if (connection.destination != newDest)\r
-        {\r
-            connection.destination = newDest;\r
-            update();\r
-        }\r
-    }\r
-\r
-    void dragStart (Point<float> pos)\r
-    {\r
-        lastInputPos = pos;\r
-        resizeToFit();\r
-    }\r
-\r
-    void dragEnd (Point<float> pos)\r
-    {\r
-        lastOutputPos = pos;\r
-        resizeToFit();\r
-    }\r
-\r
-    void update()\r
-    {\r
-        Point<float> p1, p2;\r
-        getPoints (p1, p2);\r
-\r
-        if (lastInputPos != p1 || lastOutputPos != p2)\r
-            resizeToFit();\r
-    }\r
-\r
-    void resizeToFit()\r
-    {\r
-        Point<float> p1, p2;\r
-        getPoints (p1, p2);\r
-\r
-        auto newBounds = Rectangle<float> (p1, p2).expanded (4.0f).getSmallestIntegerContainer();\r
-\r
-        if (newBounds != getBounds())\r
-            setBounds (newBounds);\r
-        else\r
-            resized();\r
-\r
-        repaint();\r
-    }\r
-\r
-    void getPoints (Point<float>& p1, Point<float>& p2) const\r
-    {\r
-        p1 = lastInputPos;\r
-        p2 = lastOutputPos;\r
-\r
-        if (auto* src = panel.getComponentForFilter (connection.source.nodeID))\r
-            p1 = src->getPinPos (connection.source.channelIndex, false);\r
-\r
-        if (auto* dest = panel.getComponentForFilter (connection.destination.nodeID))\r
-            p2 = dest->getPinPos (connection.destination.channelIndex, true);\r
-    }\r
-\r
-    void paint (Graphics& g) override\r
-    {\r
-        if (connection.source.isMIDI() || connection.destination.isMIDI())\r
-            g.setColour (Colours::red);\r
-        else\r
-            g.setColour (Colours::green);\r
-\r
-        g.fillPath (linePath);\r
-    }\r
-\r
-    bool hitTest (int x, int y) override\r
-    {\r
-        auto pos = Point<int> (x, y).toFloat();\r
-\r
-        if (hitPath.contains (pos))\r
-        {\r
-            double distanceFromStart, distanceFromEnd;\r
-            getDistancesFromEnds (pos, distanceFromStart, distanceFromEnd);\r
-\r
-            // avoid clicking the connector when over a pin\r
-            return distanceFromStart > 7.0 && distanceFromEnd > 7.0;\r
-        }\r
-\r
-        return false;\r
-    }\r
-\r
-    void mouseDown (const MouseEvent&) override\r
-    {\r
-        dragging = false;\r
-    }\r
-\r
-    void mouseDrag (const MouseEvent& e) override\r
-    {\r
-        if (dragging)\r
-        {\r
-            panel.dragConnector (e);\r
-        }\r
-        else if (e.mouseWasDraggedSinceMouseDown())\r
-        {\r
-            dragging = true;\r
-\r
-            graph.graph.removeConnection (connection);\r
-\r
-            double distanceFromStart, distanceFromEnd;\r
-            getDistancesFromEnds (getPosition().toFloat() + e.position, distanceFromStart, distanceFromEnd);\r
-            const bool isNearerSource = (distanceFromStart < distanceFromEnd);\r
-\r
-            AudioProcessorGraph::NodeAndChannel dummy { 0, 0 };\r
-\r
-            panel.beginConnectorDrag (isNearerSource ? dummy : connection.source,\r
-                                      isNearerSource ? connection.destination : dummy,\r
-                                      e);\r
-        }\r
-    }\r
-\r
-    void mouseUp (const MouseEvent& e) override\r
-    {\r
-        if (dragging)\r
-            panel.endDraggingConnector (e);\r
-    }\r
-\r
-    void resized() override\r
-    {\r
-        Point<float> p1, p2;\r
-        getPoints (p1, p2);\r
-\r
-        lastInputPos = p1;\r
-        lastOutputPos = p2;\r
-\r
-        p1 -= getPosition().toFloat();\r
-        p2 -= getPosition().toFloat();\r
-\r
-        linePath.clear();\r
-        linePath.startNewSubPath (p1);\r
-        linePath.cubicTo (p1.x, p1.y + (p2.y - p1.y) * 0.33f,\r
-                          p2.x, p1.y + (p2.y - p1.y) * 0.66f,\r
-                          p2.x, p2.y);\r
-\r
-        PathStrokeType wideStroke (8.0f);\r
-        wideStroke.createStrokedPath (hitPath, linePath);\r
-\r
-        PathStrokeType stroke (2.5f);\r
-        stroke.createStrokedPath (linePath, linePath);\r
-\r
-        auto arrowW = 5.0f;\r
-        auto arrowL = 4.0f;\r
-\r
-        Path arrow;\r
-        arrow.addTriangle (-arrowL, arrowW,\r
-                           -arrowL, -arrowW,\r
-                           arrowL, 0.0f);\r
-\r
-        arrow.applyTransform (AffineTransform()\r
-                                .rotated (MathConstants<float>::halfPi - (float) atan2 (p2.x - p1.x, p2.y - p1.y))\r
-                                .translated ((p1 + p2) * 0.5f));\r
-\r
-        linePath.addPath (arrow);\r
-        linePath.setUsingNonZeroWinding (true);\r
-    }\r
-\r
-    void getDistancesFromEnds (Point<float> p, double& distanceFromStart, double& distanceFromEnd) const\r
-    {\r
-        Point<float> p1, p2;\r
-        getPoints (p1, p2);\r
-\r
-        distanceFromStart = p1.getDistanceFrom (p);\r
-        distanceFromEnd   = p2.getDistanceFrom (p);\r
-    }\r
-\r
-    GraphEditorPanel& panel;\r
-    FilterGraph& graph;\r
-    AudioProcessorGraph::Connection connection { { 0, 0 }, { 0, 0 } };\r
-    Point<float> lastInputPos, lastOutputPos;\r
-    Path linePath, hitPath;\r
-    bool dragging = false;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectorComponent)\r
-};\r
-\r
-\r
-//==============================================================================\r
-GraphEditorPanel::GraphEditorPanel (FilterGraph& g)  : graph (g)\r
-{\r
-    graph.addChangeListener (this);\r
-    setOpaque (true);\r
-}\r
-\r
-GraphEditorPanel::~GraphEditorPanel()\r
-{\r
-    graph.removeChangeListener (this);\r
-    draggingConnector = nullptr;\r
-    nodes.clear();\r
-    connectors.clear();\r
-}\r
-\r
-void GraphEditorPanel::paint (Graphics& g)\r
-{\r
-    g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r
-}\r
-\r
-void GraphEditorPanel::mouseDown (const MouseEvent& e)\r
-{\r
-    if (e.mods.isPopupMenu())\r
-    {\r
-        PopupMenu m;\r
-\r
-        if (auto* mainWindow = findParentComponentOfClass<MainHostWindow>())\r
-        {\r
-            mainWindow->addPluginsToMenu (m);\r
-\r
-            auto r = m.show();\r
-\r
-            if (auto* desc = mainWindow->getChosenType (r))\r
-                createNewPlugin (*desc, e.position.toInt());\r
-        }\r
-    }\r
-}\r
-\r
-void GraphEditorPanel::createNewPlugin (const PluginDescription& desc, Point<int> position)\r
-{\r
-    graph.addPlugin (desc, position.toDouble() / Point<double> ((double) getWidth(), (double) getHeight()));\r
-}\r
-\r
-GraphEditorPanel::FilterComponent* GraphEditorPanel::getComponentForFilter (const uint32 filterID) const\r
-{\r
-    for (auto* fc : nodes)\r
-       if (fc->pluginID == filterID)\r
-            return fc;\r
-\r
-    return nullptr;\r
-}\r
-\r
-GraphEditorPanel::ConnectorComponent* GraphEditorPanel::getComponentForConnection (const AudioProcessorGraph::Connection& conn) const\r
-{\r
-    for (auto* cc : connectors)\r
-        if (cc->connection == conn)\r
-            return cc;\r
-\r
-    return nullptr;\r
-}\r
-\r
-GraphEditorPanel::PinComponent* GraphEditorPanel::findPinAt (Point<float> pos) const\r
-{\r
-    for (auto* fc : nodes)\r
-    {\r
-        // NB: A Visual Studio optimiser error means we have to put this Component* in a local\r
-        // variable before trying to cast it, or it gets mysteriously optimised away..\r
-        auto* comp = fc->getComponentAt (pos.toInt() - fc->getPosition());\r
-\r
-        if (auto* pin = dynamic_cast<PinComponent*> (comp))\r
-            return pin;\r
-    }\r
-\r
-    return nullptr;\r
-}\r
-\r
-void GraphEditorPanel::resized()\r
-{\r
-    updateComponents();\r
-}\r
-\r
-void GraphEditorPanel::changeListenerCallback (ChangeBroadcaster*)\r
-{\r
-    updateComponents();\r
-}\r
-\r
-void GraphEditorPanel::updateComponents()\r
-{\r
-    for (int i = nodes.size(); --i >= 0;)\r
-        if (graph.graph.getNodeForId (nodes.getUnchecked(i)->pluginID) == nullptr)\r
-            nodes.remove (i);\r
-\r
-    for (int i = connectors.size(); --i >= 0;)\r
-        if (! graph.graph.isConnected (connectors.getUnchecked(i)->connection))\r
-            connectors.remove (i);\r
-\r
-    for (auto* fc : nodes)\r
-        fc->update();\r
-\r
-    for (auto* cc : connectors)\r
-        cc->update();\r
-\r
-    for (auto* f : graph.graph.getNodes())\r
-    {\r
-        if (getComponentForFilter (f->nodeID) == 0)\r
-        {\r
-            auto* comp = nodes.add (new FilterComponent (*this, f->nodeID));\r
-            addAndMakeVisible (comp);\r
-            comp->update();\r
-        }\r
-    }\r
-\r
-    for (auto& c : graph.graph.getConnections())\r
-    {\r
-        if (getComponentForConnection (c) == 0)\r
-        {\r
-            auto* comp = connectors.add (new ConnectorComponent (*this));\r
-            addAndMakeVisible (comp);\r
-\r
-            comp->setInput (c.source);\r
-            comp->setOutput (c.destination);\r
-        }\r
-    }\r
-}\r
-\r
-void GraphEditorPanel::beginConnectorDrag (AudioProcessorGraph::NodeAndChannel source,\r
-                                           AudioProcessorGraph::NodeAndChannel dest,\r
-                                           const MouseEvent& e)\r
-{\r
-    auto* c = dynamic_cast<ConnectorComponent*> (e.originalComponent);\r
-    connectors.removeObject (c, false);\r
-    draggingConnector = c;\r
-\r
-    if (draggingConnector == nullptr)\r
-        draggingConnector = new ConnectorComponent (*this);\r
-\r
-    draggingConnector->setInput (source);\r
-    draggingConnector->setOutput (dest);\r
-\r
-    addAndMakeVisible (draggingConnector);\r
-    draggingConnector->toFront (false);\r
-\r
-    dragConnector (e);\r
-}\r
-\r
-void GraphEditorPanel::dragConnector (const MouseEvent& e)\r
-{\r
-    auto e2 = e.getEventRelativeTo (this);\r
-\r
-    if (draggingConnector != nullptr)\r
-    {\r
-        draggingConnector->setTooltip ({});\r
-\r
-        auto pos = e2.position;\r
-\r
-        if (auto* pin = findPinAt (pos))\r
-        {\r
-            auto connection = draggingConnector->connection;\r
-\r
-            if (connection.source.nodeID == 0 && ! pin->isInput)\r
-            {\r
-                connection.source = pin->pin;\r
-            }\r
-            else if (connection.destination.nodeID == 0 && pin->isInput)\r
-            {\r
-                connection.destination = pin->pin;\r
-            }\r
-\r
-            if (graph.graph.canConnect (connection))\r
-            {\r
-                pos = (pin->getParentComponent()->getPosition() + pin->getBounds().getCentre()).toFloat();\r
-                draggingConnector->setTooltip (pin->getTooltip());\r
-            }\r
-        }\r
-\r
-        if (draggingConnector->connection.source.nodeID == 0)\r
-            draggingConnector->dragStart (pos);\r
-        else\r
-            draggingConnector->dragEnd (pos);\r
-    }\r
-}\r
-\r
-void GraphEditorPanel::endDraggingConnector (const MouseEvent& e)\r
-{\r
-    if (draggingConnector == nullptr)\r
-        return;\r
-\r
-    draggingConnector->setTooltip ({});\r
-\r
-    auto e2 = e.getEventRelativeTo (this);\r
-    auto connection = draggingConnector->connection;\r
-\r
-    draggingConnector = nullptr;\r
-\r
-    if (auto* pin = findPinAt (e2.position))\r
-    {\r
-        if (connection.source.nodeID == 0)\r
-        {\r
-            if (pin->isInput)\r
-                return;\r
-\r
-            connection.source = pin->pin;\r
-        }\r
-        else\r
-        {\r
-            if (! pin->isInput)\r
-                return;\r
-\r
-            connection.destination = pin->pin;\r
-        }\r
-\r
-        graph.graph.addConnection (connection);\r
-    }\r
-}\r
-\r
-//==============================================================================\r
-struct GraphDocumentComponent::TooltipBar   : public Component,\r
-                                              private Timer\r
-{\r
-    TooltipBar()\r
-    {\r
-        startTimer (100);\r
-    }\r
-\r
-    void paint (Graphics& g) override\r
-    {\r
-        g.setFont (Font (getHeight() * 0.7f, Font::bold));\r
-        g.setColour (Colours::black);\r
-        g.drawFittedText (tip, 10, 0, getWidth() - 12, getHeight(), Justification::centredLeft, 1);\r
-    }\r
-\r
-    void timerCallback() override\r
-    {\r
-        String newTip;\r
-\r
-        if (auto* underMouse = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse())\r
-            if (auto* ttc = dynamic_cast<TooltipClient*> (underMouse))\r
-                if (! (underMouse->isMouseButtonDown() || underMouse->isCurrentlyBlockedByAnotherModalComponent()))\r
-                    newTip = ttc->getTooltip();\r
-\r
-        if (newTip != tip)\r
-        {\r
-            tip = newTip;\r
-            repaint();\r
-        }\r
-    }\r
-\r
-    String tip;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TooltipBar)\r
-};\r
-\r
-//==============================================================================\r
-GraphDocumentComponent::GraphDocumentComponent (AudioPluginFormatManager& fm, AudioDeviceManager& dm)\r
-    : graph (new FilterGraph (fm)), deviceManager (dm),\r
-      graphPlayer (getAppProperties().getUserSettings()->getBoolValue ("doublePrecisionProcessing", false))\r
-{\r
-    addAndMakeVisible (graphPanel = new GraphEditorPanel (*graph));\r
-\r
-    deviceManager.addChangeListener (graphPanel);\r
-\r
-    graphPlayer.setProcessor (&graph->graph);\r
-\r
-    keyState.addListener (&graphPlayer.getMidiMessageCollector());\r
-\r
-    addAndMakeVisible (keyboardComp = new MidiKeyboardComponent (keyState, MidiKeyboardComponent::horizontalKeyboard));\r
-    addAndMakeVisible (statusBar = new TooltipBar());\r
-\r
-    deviceManager.addAudioCallback (&graphPlayer);\r
-    deviceManager.addMidiInputCallback (String(), &graphPlayer.getMidiMessageCollector());\r
-\r
-    graphPanel->updateComponents();\r
-}\r
-\r
-GraphDocumentComponent::~GraphDocumentComponent()\r
-{\r
-    releaseGraph();\r
-\r
-    keyState.removeListener (&graphPlayer.getMidiMessageCollector());\r
-}\r
-\r
-void GraphDocumentComponent::resized()\r
-{\r
-    const int keysHeight = 60;\r
-    const int statusHeight = 20;\r
-\r
-    graphPanel->setBounds (0, 0, getWidth(), getHeight() - keysHeight);\r
-    statusBar->setBounds (0, getHeight() - keysHeight - statusHeight, getWidth(), statusHeight);\r
-    keyboardComp->setBounds (0, getHeight() - keysHeight, getWidth(), keysHeight);\r
-}\r
-\r
-void GraphDocumentComponent::createNewPlugin (const PluginDescription& desc, Point<int> pos)\r
-{\r
-    graphPanel->createNewPlugin (desc, pos);\r
-}\r
-\r
-void GraphDocumentComponent::unfocusKeyboardComponent()\r
-{\r
-    keyboardComp->unfocusAllComponents();\r
-}\r
-\r
-void GraphDocumentComponent::releaseGraph()\r
-{\r
-    deviceManager.removeAudioCallback (&graphPlayer);\r
-    deviceManager.removeMidiInputCallback (String(), &graphPlayer.getMidiMessageCollector());\r
-\r
-    if (graphPanel != nullptr)\r
-    {\r
-        deviceManager.removeChangeListener (graphPanel);\r
-        graphPanel = nullptr;\r
-    }\r
-\r
-    keyboardComp = nullptr;\r
-    statusBar = nullptr;\r
-\r
-    graphPlayer.setProcessor (nullptr);\r
-    graph = nullptr;\r
-}\r
-\r
-void GraphDocumentComponent::setDoublePrecision (bool doublePrecision)\r
-{\r
-    graphPlayer.setDoublePrecisionProcessing (doublePrecision);\r
-}\r
-\r
-bool GraphDocumentComponent::closeAnyOpenPluginWindows()\r
-{\r
-    return graphPanel->graph.closeAnyOpenPluginWindows();\r
-}\r
diff --git a/extras/AudioPluginHost/Source/GraphEditorPanel.h b/extras/AudioPluginHost/Source/GraphEditorPanel.h
deleted file mode 100644 (file)
index 246b875..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*\r
-  ==============================================================================\r
-\r
-   This file is part of the JUCE library.\r
-   Copyright (c) 2017 - ROLI Ltd.\r
-\r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
-   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
-   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
-   27th April 2017).\r
-\r
-   End User License Agreement: www.juce.com/juce-5-licence\r
-   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
-   Or: You may also use this code under the terms of the GPL v3 (see\r
-   www.gnu.org/licenses).\r
-\r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
-\r
-  ==============================================================================\r
-*/\r
-\r
-#pragma once\r
-\r
-#include "FilterGraph.h"\r
-\r
-\r
-//==============================================================================\r
-/**\r
-    A panel that displays and edits a FilterGraph.\r
-*/\r
-class GraphEditorPanel   : public Component,\r
-                           public ChangeListener\r
-{\r
-public:\r
-    GraphEditorPanel (FilterGraph& graph);\r
-    ~GraphEditorPanel();\r
-\r
-    void createNewPlugin (const PluginDescription&, Point<int> position);\r
-\r
-    void paint (Graphics&) override;\r
-    void mouseDown (const MouseEvent&) override;\r
-    void resized() override;\r
-    void changeListenerCallback (ChangeBroadcaster*) override;\r
-    void updateComponents();\r
-\r
-    //==============================================================================\r
-    void beginConnectorDrag (AudioProcessorGraph::NodeAndChannel source,\r
-                             AudioProcessorGraph::NodeAndChannel dest,\r
-                             const MouseEvent&);\r
-    void dragConnector (const MouseEvent&);\r
-    void endDraggingConnector (const MouseEvent&);\r
-\r
-    //==============================================================================\r
-    FilterGraph& graph;\r
-\r
-private:\r
-    struct FilterComponent;\r
-    struct ConnectorComponent;\r
-    struct PinComponent;\r
-\r
-    OwnedArray<FilterComponent> nodes;\r
-    OwnedArray<ConnectorComponent> connectors;\r
-    ScopedPointer<ConnectorComponent> draggingConnector;\r
-\r
-    FilterComponent* getComponentForFilter (AudioProcessorGraph::NodeID) const;\r
-    ConnectorComponent* getComponentForConnection (const AudioProcessorGraph::Connection&) const;\r
-    PinComponent* findPinAt (Point<float>) const;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GraphEditorPanel)\r
-};\r
-\r
-\r
-//==============================================================================\r
-/**\r
-    A panel that embeds a GraphEditorPanel with a midi keyboard at the bottom.\r
-\r
-    It also manages the graph itself, and plays it.\r
-*/\r
-class GraphDocumentComponent  : public Component\r
-{\r
-public:\r
-    GraphDocumentComponent (AudioPluginFormatManager& formatManager,\r
-                            AudioDeviceManager& deviceManager);\r
-    ~GraphDocumentComponent();\r
-\r
-    //==============================================================================\r
-    void createNewPlugin (const PluginDescription&, Point<int> position);\r
-    void setDoublePrecision (bool doublePrecision);\r
-    bool closeAnyOpenPluginWindows();\r
-\r
-    //==============================================================================\r
-    ScopedPointer<FilterGraph> graph;\r
-\r
-    void resized();\r
-    void unfocusKeyboardComponent();\r
-    void releaseGraph();\r
-\r
-    ScopedPointer<GraphEditorPanel> graphPanel;\r
-    ScopedPointer<MidiKeyboardComponent> keyboardComp;\r
-\r
-private:\r
-    //==============================================================================\r
-    AudioDeviceManager& deviceManager;\r
-    AudioProcessorPlayer graphPlayer;\r
-    MidiKeyboardState keyState;\r
-\r
-    struct TooltipBar;\r
-    ScopedPointer<TooltipBar> statusBar;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GraphDocumentComponent)\r
-};\r
index 9cfe5b465f452568577058400dc89cc963df6e03..b350f6420e46e6190a3a86d479a857da24bcdd6c 100644 (file)
@@ -25,8 +25,8 @@
 */\r
 \r
 #include "../JuceLibraryCode/JuceHeader.h"\r
-#include "MainHostWindow.h"\r
-#include "InternalFilters.h"\r
+#include "UI/MainHostWindow.h"\r
+#include "Filters/InternalFilters.h"\r
 \r
 #if ! (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_AU)\r
  #error "If you're building the audio plugin host, you probably want to enable VST and/or AU support"\r
@@ -75,6 +75,9 @@ public:
     {\r
         File fileToOpen;\r
 \r
+       #if JUCE_ANDROID || JUCE_IOS\r
+        fileToOpen = FilterGraph::getDefaultGraphDocumentOnMobile();\r
+       #else\r
         for (int i = 0; i < getCommandLineParameterArray().size(); ++i)\r
         {\r
             fileToOpen = File::getCurrentWorkingDirectory().getChildFile (getCommandLineParameterArray()[i]);\r
@@ -82,6 +85,7 @@ public:
             if (fileToOpen.existsAsFile())\r
                 break;\r
         }\r
+       #endif\r
 \r
         if (! fileToOpen.existsAsFile())\r
         {\r
@@ -105,6 +109,15 @@ public:
         LookAndFeel::setDefaultLookAndFeel (nullptr);\r
     }\r
 \r
+    void suspended() override\r
+    {\r
+       #if JUCE_ANDROID || JUCE_IOS\r
+        if (GraphDocumentComponent* graph = mainWindow->graphHolder.get())\r
+            if (FilterGraph* ioGraph = graph->graph.get())\r
+                ioGraph->saveDocument (FilterGraph::getDefaultGraphDocumentOnMobile());\r
+       #endif\r
+    }\r
+\r
     void systemRequestedQuit() override\r
     {\r
         if (mainWindow != nullptr)\r
@@ -113,6 +126,12 @@ public:
             JUCEApplicationBase::quit();\r
     }\r
 \r
+    void backButtonPressed() override\r
+    {\r
+        if (mainWindow->graphHolder != nullptr)\r
+            mainWindow->graphHolder->hideLastSidePanel();\r
+    }\r
+\r
     const String getApplicationName() override       { return "Juce Plug-In Host"; }\r
     const String getApplicationVersion() override    { return ProjectInfo::versionString; }\r
     bool moreThanOneInstanceAllowed() override       { return true; }\r
@@ -124,10 +143,12 @@ private:
     ScopedPointer<MainHostWindow> mainWindow;\r
 };\r
 \r
-static PluginHostApp& getApp()                      { return *dynamic_cast<PluginHostApp*>(JUCEApplication::getInstance()); }\r
-ApplicationCommandManager& getCommandManager()      { return getApp().commandManager; }\r
-ApplicationProperties& getAppProperties()           { return *getApp().appProperties; }\r
+static PluginHostApp& getApp()                    { return *dynamic_cast<PluginHostApp*>(JUCEApplication::getInstance()); }\r
+\r
+ApplicationProperties& getAppProperties()         { return *getApp().appProperties; }\r
+ApplicationCommandManager& getCommandManager()    { return getApp().commandManager; }\r
 \r
+bool isOnTouchDevice()                            { return Desktop::getInstance().getMainMouseSource().isTouch(); }\r
 \r
 // This kicks the whole thing off..\r
 START_JUCE_APPLICATION (PluginHostApp)\r
diff --git a/extras/AudioPluginHost/Source/InternalFilters.cpp b/extras/AudioPluginHost/Source/InternalFilters.cpp
deleted file mode 100644 (file)
index 497c828..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*\r
-  ==============================================================================\r
-\r
-   This file is part of the JUCE library.\r
-   Copyright (c) 2017 - ROLI Ltd.\r
-\r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
-   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
-   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
-   27th April 2017).\r
-\r
-   End User License Agreement: www.juce.com/juce-5-licence\r
-   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
-   Or: You may also use this code under the terms of the GPL v3 (see\r
-   www.gnu.org/licenses).\r
-\r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
-\r
-  ==============================================================================\r
-*/\r
-\r
-#include "../JuceLibraryCode/JuceHeader.h"\r
-#include "InternalFilters.h"\r
-#include "FilterGraph.h"\r
-\r
-\r
-//==============================================================================\r
-InternalPluginFormat::InternalPluginFormat()\r
-{\r
-    {\r
-        AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);\r
-        p.fillInPluginDescription (audioOutDesc);\r
-    }\r
-\r
-    {\r
-        AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode);\r
-        p.fillInPluginDescription (audioInDesc);\r
-    }\r
-\r
-    {\r
-        AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode);\r
-        p.fillInPluginDescription (midiInDesc);\r
-    }\r
-}\r
-\r
-AudioPluginInstance* InternalPluginFormat::createInstance (const String& name)\r
-{\r
-    if (name == audioOutDesc.name) return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);\r
-    if (name == audioInDesc.name)  return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode);\r
-    if (name == midiInDesc.name)   return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode);\r
-\r
-    return nullptr;\r
-}\r
-\r
-void InternalPluginFormat::createPluginInstance (const PluginDescription& desc,\r
-                                                 double /*initialSampleRate*/,\r
-                                                 int /*initialBufferSize*/,\r
-                                                 void* userData,\r
-                                                 void (*callback) (void*, AudioPluginInstance*, const String&))\r
-{\r
-    auto* p = createInstance (desc.name);\r
-\r
-    callback (userData, p, p == nullptr ? NEEDS_TRANS ("Invalid internal filter name") : String());\r
-}\r
-\r
-bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept\r
-{\r
-    return false;\r
-}\r
-\r
-void InternalPluginFormat::getAllTypes (OwnedArray<PluginDescription>& results)\r
-{\r
-    results.add (new PluginDescription (audioInDesc));\r
-    results.add (new PluginDescription (audioOutDesc));\r
-    results.add (new PluginDescription (midiInDesc));\r
-}\r
diff --git a/extras/AudioPluginHost/Source/InternalFilters.h b/extras/AudioPluginHost/Source/InternalFilters.h
deleted file mode 100644 (file)
index cdcde6d..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*\r
-  ==============================================================================\r
-\r
-   This file is part of the JUCE library.\r
-   Copyright (c) 2017 - ROLI Ltd.\r
-\r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
-   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
-   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
-   27th April 2017).\r
-\r
-   End User License Agreement: www.juce.com/juce-5-licence\r
-   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
-   Or: You may also use this code under the terms of the GPL v3 (see\r
-   www.gnu.org/licenses).\r
-\r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
-\r
-  ==============================================================================\r
-*/\r
-\r
-#pragma once\r
-\r
-#include "FilterGraph.h"\r
-\r
-\r
-//==============================================================================\r
-/**\r
-    Manages the internal plugin types.\r
-*/\r
-class InternalPluginFormat   : public AudioPluginFormat\r
-{\r
-public:\r
-    //==============================================================================\r
-    InternalPluginFormat();\r
-    ~InternalPluginFormat() {}\r
-\r
-    //==============================================================================\r
-    PluginDescription audioInDesc, audioOutDesc, midiInDesc;\r
-\r
-    void getAllTypes (OwnedArray<PluginDescription>&);\r
-\r
-    //==============================================================================\r
-    String getName() const override                                                     { return "Internal"; }\r
-    bool fileMightContainThisPluginType (const String&) override                        { return true; }\r
-    FileSearchPath getDefaultLocationsToSearch() override                               { return {}; }\r
-    bool canScanForPlugins() const override                                             { return false; }\r
-    void findAllTypesForFile (OwnedArray <PluginDescription>&, const String&) override  {}\r
-    bool doesPluginStillExist (const PluginDescription&) override                       { return true; }\r
-    String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override      { return fileOrIdentifier; }\r
-    bool pluginNeedsRescanning (const PluginDescription&) override                      { return false; }\r
-    StringArray searchPathsForPlugins (const FileSearchPath&, bool, bool) override      { return {}; }\r
-\r
-private:\r
-    //==============================================================================\r
-    void createPluginInstance (const PluginDescription&, double initialSampleRate, int initialBufferSize,\r
-                               void* userData, void (*callback) (void*, AudioPluginInstance*, const String&)) override;\r
-    AudioPluginInstance* createInstance (const String& name);\r
-\r
-    bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override;\r
-};\r
diff --git a/extras/AudioPluginHost/Source/JUCEAppIcon.png b/extras/AudioPluginHost/Source/JUCEAppIcon.png
new file mode 100644 (file)
index 0000000..2564a24
Binary files /dev/null and b/extras/AudioPluginHost/Source/JUCEAppIcon.png differ
diff --git a/extras/AudioPluginHost/Source/MainHostWindow.cpp b/extras/AudioPluginHost/Source/MainHostWindow.cpp
deleted file mode 100644 (file)
index 7d7c7ba..0000000
+++ /dev/null
@@ -1,604 +0,0 @@
-/*\r
-  ==============================================================================\r
-\r
-   This file is part of the JUCE library.\r
-   Copyright (c) 2017 - ROLI Ltd.\r
-\r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
-   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
-   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
-   27th April 2017).\r
-\r
-   End User License Agreement: www.juce.com/juce-5-licence\r
-   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
-   Or: You may also use this code under the terms of the GPL v3 (see\r
-   www.gnu.org/licenses).\r
-\r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
-\r
-  ==============================================================================\r
-*/\r
-\r
-#include "../JuceLibraryCode/JuceHeader.h"\r
-#include "MainHostWindow.h"\r
-#include "InternalFilters.h"\r
-\r
-\r
-//==============================================================================\r
-class MainHostWindow::PluginListWindow  : public DocumentWindow\r
-{\r
-public:\r
-    PluginListWindow (MainHostWindow& mw, AudioPluginFormatManager& pluginFormatManager)\r
-        : DocumentWindow ("Available Plugins",\r
-                          LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),\r
-                          DocumentWindow::minimiseButton | DocumentWindow::closeButton),\r
-          owner (mw)\r
-    {\r
-        auto deadMansPedalFile = getAppProperties().getUserSettings()\r
-                                   ->getFile().getSiblingFile ("RecentlyCrashedPluginsList");\r
-\r
-        setContentOwned (new PluginListComponent (pluginFormatManager,\r
-                                                  owner.knownPluginList,\r
-                                                  deadMansPedalFile,\r
-                                                  getAppProperties().getUserSettings(), true), true);\r
-\r
-        setResizable (true, false);\r
-        setResizeLimits (300, 400, 800, 1500);\r
-        setTopLeftPosition (60, 60);\r
-\r
-        restoreWindowStateFromString (getAppProperties().getUserSettings()->getValue ("listWindowPos"));\r
-        setVisible (true);\r
-    }\r
-\r
-    ~PluginListWindow()\r
-    {\r
-        getAppProperties().getUserSettings()->setValue ("listWindowPos", getWindowStateAsString());\r
-        clearContentComponent();\r
-    }\r
-\r
-    void closeButtonPressed() override\r
-    {\r
-        owner.pluginListWindow = nullptr;\r
-    }\r
-\r
-private:\r
-    MainHostWindow& owner;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListWindow)\r
-};\r
-\r
-//==============================================================================\r
-MainHostWindow::MainHostWindow()\r
-    : DocumentWindow (JUCEApplication::getInstance()->getApplicationName(),\r
-                      LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),\r
-                      DocumentWindow::allButtons)\r
-{\r
-    formatManager.addDefaultFormats();\r
-    formatManager.addFormat (new InternalPluginFormat());\r
-\r
-    ScopedPointer<XmlElement> savedAudioState (getAppProperties().getUserSettings()\r
-                                                   ->getXmlValue ("audioDeviceState"));\r
-\r
-    deviceManager.initialise (256, 256, savedAudioState, true);\r
-\r
-    setResizable (true, false);\r
-    setResizeLimits (500, 400, 10000, 10000);\r
-    centreWithSize (800, 600);\r
-\r
-    graphHolder = new GraphDocumentComponent (formatManager, deviceManager);\r
-\r
-    setContentNonOwned (graphHolder, false);\r
-\r
-    restoreWindowStateFromString (getAppProperties().getUserSettings()->getValue ("mainWindowPos"));\r
-\r
-    setVisible (true);\r
-\r
-    InternalPluginFormat internalFormat;\r
-    internalFormat.getAllTypes (internalTypes);\r
-\r
-    ScopedPointer<XmlElement> savedPluginList (getAppProperties().getUserSettings()->getXmlValue ("pluginList"));\r
-\r
-    if (savedPluginList != nullptr)\r
-        knownPluginList.recreateFromXml (*savedPluginList);\r
-\r
-    pluginSortMethod = (KnownPluginList::SortMethod) getAppProperties().getUserSettings()\r
-                            ->getIntValue ("pluginSortMethod", KnownPluginList::sortByManufacturer);\r
-\r
-    knownPluginList.addChangeListener (this);\r
-\r
-    if (auto* filterGraph = graphHolder->graph.get())\r
-        filterGraph->addChangeListener (this);\r
-\r
-    addKeyListener (getCommandManager().getKeyMappings());\r
-\r
-    Process::setPriority (Process::HighPriority);\r
-\r
-   #if JUCE_MAC\r
-    setMacMainMenu (this);\r
-   #else\r
-    setMenuBar (this);\r
-   #endif\r
-\r
-    getCommandManager().setFirstCommandTarget (this);\r
-}\r
-\r
-MainHostWindow::~MainHostWindow()\r
-{\r
-    pluginListWindow = nullptr;\r
-    knownPluginList.removeChangeListener (this);\r
-\r
-    if (auto* filterGraph = graphHolder->graph.get())\r
-        filterGraph->removeChangeListener (this);\r
-\r
-    getAppProperties().getUserSettings()->setValue ("mainWindowPos", getWindowStateAsString());\r
-    clearContentComponent();\r
-\r
-   #if JUCE_MAC\r
-    setMacMainMenu (nullptr);\r
-   #else\r
-    setMenuBar (nullptr);\r
-   #endif\r
-\r
-    graphHolder = nullptr;\r
-}\r
-\r
-void MainHostWindow::closeButtonPressed()\r
-{\r
-    tryToQuitApplication();\r
-}\r
-\r
-struct AsyncQuitRetrier  : private Timer\r
-{\r
-    AsyncQuitRetrier()   { startTimer (500); }\r
-\r
-    void timerCallback() override\r
-    {\r
-        stopTimer();\r
-        delete this;\r
-\r
-        if (auto app = JUCEApplicationBase::getInstance())\r
-            app->systemRequestedQuit();\r
-    }\r
-};\r
-\r
-void MainHostWindow::tryToQuitApplication()\r
-{\r
-    if (graphHolder->closeAnyOpenPluginWindows())\r
-    {\r
-        // Really important thing to note here: if the last call just deleted any plugin windows,\r
-        // we won't exit immediately - instead we'll use our AsyncQuitRetrier to let the message\r
-        // loop run for another brief moment, then try again. This will give any plugins a chance\r
-        // to flush any GUI events that may have been in transit before the app forces them to\r
-        // be unloaded\r
-        new AsyncQuitRetrier();\r
-    }\r
-    else if (ModalComponentManager::getInstance()->cancelAllModalComponents())\r
-    {\r
-        new AsyncQuitRetrier();\r
-    }\r
-    else if (graphHolder == nullptr || graphHolder->graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)\r
-    {\r
-        // Some plug-ins do not want [NSApp stop] to be called\r
-        // before the plug-ins are not deallocated.\r
-        graphHolder->releaseGraph();\r
-\r
-        JUCEApplication::quit();\r
-    }\r
-}\r
-\r
-void MainHostWindow::changeListenerCallback (ChangeBroadcaster* changed)\r
-{\r
-    if (changed == &knownPluginList)\r
-    {\r
-        menuItemsChanged();\r
-\r
-        // save the plugin list every time it gets chnaged, so that if we're scanning\r
-        // and it crashes, we've still saved the previous ones\r
-        ScopedPointer<XmlElement> savedPluginList (knownPluginList.createXml());\r
-\r
-        if (savedPluginList != nullptr)\r
-        {\r
-            getAppProperties().getUserSettings()->setValue ("pluginList", savedPluginList);\r
-            getAppProperties().saveIfNeeded();\r
-        }\r
-    }\r
-    else if (graphHolder != nullptr && changed == graphHolder->graph)\r
-    {\r
-        auto title = JUCEApplication::getInstance()->getApplicationName();\r
-        auto f = graphHolder->graph->getFile();\r
-\r
-        if (f.existsAsFile())\r
-            title = f.getFileName() + " - " + title;\r
-\r
-        setName (title);\r
-    }\r
-}\r
-\r
-StringArray MainHostWindow::getMenuBarNames()\r
-{\r
-    StringArray names;\r
-    names.add ("File");\r
-    names.add ("Plugins");\r
-    names.add ("Options");\r
-    names.add ("Windows");\r
-    return names;\r
-}\r
-\r
-PopupMenu MainHostWindow::getMenuForIndex (int topLevelMenuIndex, const String& /*menuName*/)\r
-{\r
-    PopupMenu menu;\r
-\r
-    if (topLevelMenuIndex == 0)\r
-    {\r
-        // "File" menu\r
-        menu.addCommandItem (&getCommandManager(), CommandIDs::newFile);\r
-        menu.addCommandItem (&getCommandManager(), CommandIDs::open);\r
-\r
-        RecentlyOpenedFilesList recentFiles;\r
-        recentFiles.restoreFromString (getAppProperties().getUserSettings()\r
-                                            ->getValue ("recentFilterGraphFiles"));\r
-\r
-        PopupMenu recentFilesMenu;\r
-        recentFiles.createPopupMenuItems (recentFilesMenu, 100, true, true);\r
-        menu.addSubMenu ("Open recent file", recentFilesMenu);\r
-\r
-        menu.addCommandItem (&getCommandManager(), CommandIDs::save);\r
-        menu.addCommandItem (&getCommandManager(), CommandIDs::saveAs);\r
-        menu.addSeparator();\r
-        menu.addCommandItem (&getCommandManager(), StandardApplicationCommandIDs::quit);\r
-    }\r
-    else if (topLevelMenuIndex == 1)\r
-    {\r
-        // "Plugins" menu\r
-        PopupMenu pluginsMenu;\r
-        addPluginsToMenu (pluginsMenu);\r
-        menu.addSubMenu ("Create plugin", pluginsMenu);\r
-        menu.addSeparator();\r
-        menu.addItem (250, "Delete all plugins");\r
-    }\r
-    else if (topLevelMenuIndex == 2)\r
-    {\r
-        // "Options" menu\r
-\r
-        menu.addCommandItem (&getCommandManager(), CommandIDs::showPluginListEditor);\r
-\r
-        PopupMenu sortTypeMenu;\r
-        sortTypeMenu.addItem (200, "List plugins in default order",      true, pluginSortMethod == KnownPluginList::defaultOrder);\r
-        sortTypeMenu.addItem (201, "List plugins in alphabetical order", true, pluginSortMethod == KnownPluginList::sortAlphabetically);\r
-        sortTypeMenu.addItem (202, "List plugins by category",           true, pluginSortMethod == KnownPluginList::sortByCategory);\r
-        sortTypeMenu.addItem (203, "List plugins by manufacturer",       true, pluginSortMethod == KnownPluginList::sortByManufacturer);\r
-        sortTypeMenu.addItem (204, "List plugins based on the directory structure", true, pluginSortMethod == KnownPluginList::sortByFileSystemLocation);\r
-        menu.addSubMenu ("Plugin menu type", sortTypeMenu);\r
-\r
-        menu.addSeparator();\r
-        menu.addCommandItem (&getCommandManager(), CommandIDs::showAudioSettings);\r
-        menu.addCommandItem (&getCommandManager(), CommandIDs::toggleDoublePrecision);\r
-\r
-        menu.addSeparator();\r
-        menu.addCommandItem (&getCommandManager(), CommandIDs::aboutBox);\r
-    }\r
-    else if (topLevelMenuIndex == 3)\r
-    {\r
-        menu.addCommandItem (&getCommandManager(), CommandIDs::allWindowsForward);\r
-    }\r
-\r
-    return menu;\r
-}\r
-\r
-void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/)\r
-{\r
-    if (menuItemID == 250)\r
-    {\r
-        if (graphHolder != nullptr)\r
-            if (auto* graph = graphHolder->graph.get())\r
-                graph->clear();\r
-    }\r
-    else if (menuItemID >= 100 && menuItemID < 200)\r
-    {\r
-        RecentlyOpenedFilesList recentFiles;\r
-        recentFiles.restoreFromString (getAppProperties().getUserSettings()\r
-                                            ->getValue ("recentFilterGraphFiles"));\r
-\r
-        if (graphHolder != nullptr)\r
-            if (auto* graph = graphHolder->graph.get())\r
-                if (graph != nullptr && graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)\r
-                    graph->loadFrom (recentFiles.getFile (menuItemID - 100), true);\r
-    }\r
-    else if (menuItemID >= 200 && menuItemID < 210)\r
-    {\r
-             if (menuItemID == 200)     pluginSortMethod = KnownPluginList::defaultOrder;\r
-        else if (menuItemID == 201)     pluginSortMethod = KnownPluginList::sortAlphabetically;\r
-        else if (menuItemID == 202)     pluginSortMethod = KnownPluginList::sortByCategory;\r
-        else if (menuItemID == 203)     pluginSortMethod = KnownPluginList::sortByManufacturer;\r
-        else if (menuItemID == 204)     pluginSortMethod = KnownPluginList::sortByFileSystemLocation;\r
-\r
-        getAppProperties().getUserSettings()->setValue ("pluginSortMethod", (int) pluginSortMethod);\r
-\r
-        menuItemsChanged();\r
-    }\r
-    else\r
-    {\r
-        if (auto* desc = getChosenType (menuItemID))\r
-            createPlugin (*desc,\r
-                          { proportionOfWidth  (0.3f + Random::getSystemRandom().nextFloat() * 0.6f),\r
-                            proportionOfHeight (0.3f + Random::getSystemRandom().nextFloat() * 0.6f) });\r
-    }\r
-}\r
-\r
-void MainHostWindow::menuBarActivated (bool isActivated)\r
-{\r
-    if (isActivated && graphHolder != nullptr)\r
-        graphHolder->unfocusKeyboardComponent();\r
-}\r
-\r
-void MainHostWindow::createPlugin (const PluginDescription& desc, Point<int> pos)\r
-{\r
-    if (graphHolder != nullptr)\r
-        graphHolder->createNewPlugin (desc, pos);\r
-}\r
-\r
-void MainHostWindow::addPluginsToMenu (PopupMenu& m) const\r
-{\r
-    if (graphHolder != nullptr)\r
-    {\r
-        int i = 0;\r
-\r
-        for (auto* t : internalTypes)\r
-            m.addItem (++i, t->name + " (" + t->pluginFormatName + ")",\r
-                       graphHolder->graph->getNodeForName (t->name) == nullptr);\r
-    }\r
-\r
-    m.addSeparator();\r
-\r
-    knownPluginList.addToMenu (m, pluginSortMethod);\r
-}\r
-\r
-const PluginDescription* MainHostWindow::getChosenType (const int menuID) const\r
-{\r
-    if (menuID >= 1 && menuID < 1 + internalTypes.size())\r
-        return internalTypes [menuID - 1];\r
-\r
-    return knownPluginList.getType (knownPluginList.getIndexChosenByMenu (menuID));\r
-}\r
-\r
-//==============================================================================\r
-ApplicationCommandTarget* MainHostWindow::getNextCommandTarget()\r
-{\r
-    return findFirstTargetParentComponent();\r
-}\r
-\r
-void MainHostWindow::getAllCommands (Array<CommandID>& commands)\r
-{\r
-    // this returns the set of all commands that this target can perform..\r
-    const CommandID ids[] = { CommandIDs::newFile,\r
-                              CommandIDs::open,\r
-                              CommandIDs::save,\r
-                              CommandIDs::saveAs,\r
-                              CommandIDs::showPluginListEditor,\r
-                              CommandIDs::showAudioSettings,\r
-                              CommandIDs::toggleDoublePrecision,\r
-                              CommandIDs::aboutBox,\r
-                              CommandIDs::allWindowsForward\r
-                            };\r
-\r
-    commands.addArray (ids, numElementsInArray (ids));\r
-}\r
-\r
-void MainHostWindow::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result)\r
-{\r
-    const String category ("General");\r
-\r
-    switch (commandID)\r
-    {\r
-    case CommandIDs::newFile:\r
-        result.setInfo ("New", "Creates a new filter graph file", category, 0);\r
-        result.defaultKeypresses.add(KeyPress('n', ModifierKeys::commandModifier, 0));\r
-        break;\r
-\r
-    case CommandIDs::open:\r
-        result.setInfo ("Open...", "Opens a filter graph file", category, 0);\r
-        result.defaultKeypresses.add (KeyPress ('o', ModifierKeys::commandModifier, 0));\r
-        break;\r
-\r
-    case CommandIDs::save:\r
-        result.setInfo ("Save", "Saves the current graph to a file", category, 0);\r
-        result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier, 0));\r
-        break;\r
-\r
-    case CommandIDs::saveAs:\r
-        result.setInfo ("Save As...",\r
-                        "Saves a copy of the current graph to a file",\r
-                        category, 0);\r
-        result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::shiftModifier | ModifierKeys::commandModifier, 0));\r
-        break;\r
-\r
-    case CommandIDs::showPluginListEditor:\r
-        result.setInfo ("Edit the list of available plug-Ins...", String(), category, 0);\r
-        result.addDefaultKeypress ('p', ModifierKeys::commandModifier);\r
-        break;\r
-\r
-    case CommandIDs::showAudioSettings:\r
-        result.setInfo ("Change the audio device settings", String(), category, 0);\r
-        result.addDefaultKeypress ('a', ModifierKeys::commandModifier);\r
-        break;\r
-\r
-    case CommandIDs::toggleDoublePrecision:\r
-        updatePrecisionMenuItem (result);\r
-        break;\r
-\r
-    case CommandIDs::aboutBox:\r
-        result.setInfo ("About...", String(), category, 0);\r
-        break;\r
-\r
-    case CommandIDs::allWindowsForward:\r
-        result.setInfo ("All Windows Forward", "Bring all plug-in windows forward", category, 0);\r
-        result.addDefaultKeypress ('w', ModifierKeys::commandModifier);\r
-        break;\r
-\r
-    default:\r
-        break;\r
-    }\r
-}\r
-\r
-bool MainHostWindow::perform (const InvocationInfo& info)\r
-{\r
-    switch (info.commandID)\r
-    {\r
-    case CommandIDs::newFile:\r
-        if (graphHolder != nullptr && graphHolder->graph != nullptr && graphHolder->graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)\r
-            graphHolder->graph->newDocument();\r
-        break;\r
-\r
-    case CommandIDs::open:\r
-        if (graphHolder != nullptr && graphHolder->graph != nullptr && graphHolder->graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)\r
-            graphHolder->graph->loadFromUserSpecifiedFile (true);\r
-        break;\r
-\r
-    case CommandIDs::save:\r
-        if (graphHolder != nullptr && graphHolder->graph != nullptr)\r
-            graphHolder->graph->save (true, true);\r
-        break;\r
-\r
-    case CommandIDs::saveAs:\r
-        if (graphHolder != nullptr && graphHolder->graph != nullptr)\r
-            graphHolder->graph->saveAs (File(), true, true, true);\r
-        break;\r
-\r
-    case CommandIDs::showPluginListEditor:\r
-        if (pluginListWindow == nullptr)\r
-            pluginListWindow = new PluginListWindow (*this, formatManager);\r
-\r
-        pluginListWindow->toFront (true);\r
-        break;\r
-\r
-    case CommandIDs::showAudioSettings:\r
-        showAudioSettings();\r
-        break;\r
-\r
-    case CommandIDs::toggleDoublePrecision:\r
-        if (auto* props = getAppProperties().getUserSettings())\r
-        {\r
-            bool newIsDoublePrecision = ! isDoublePrecisionProcessing();\r
-            props->setValue ("doublePrecisionProcessing", var (newIsDoublePrecision));\r
-\r
-            {\r
-                ApplicationCommandInfo cmdInfo (info.commandID);\r
-                updatePrecisionMenuItem (cmdInfo);\r
-                menuItemsChanged();\r
-            }\r
-\r
-            if (graphHolder != nullptr)\r
-                graphHolder->setDoublePrecision (newIsDoublePrecision);\r
-        }\r
-        break;\r
-\r
-    case CommandIDs::aboutBox:\r
-        // TODO\r
-        break;\r
-\r
-    case CommandIDs::allWindowsForward:\r
-    {\r
-        auto& desktop = Desktop::getInstance();\r
-\r
-        for (int i = 0; i < desktop.getNumComponents(); ++i)\r
-            desktop.getComponent (i)->toBehind (this);\r
-\r
-        break;\r
-    }\r
-\r
-    default:\r
-        return false;\r
-    }\r
-\r
-    return true;\r
-}\r
-\r
-void MainHostWindow::showAudioSettings()\r
-{\r
-    AudioDeviceSelectorComponent audioSettingsComp (deviceManager,\r
-                                                    0, 256,\r
-                                                    0, 256,\r
-                                                    true, true, true, false);\r
-\r
-    audioSettingsComp.setSize (500, 450);\r
-\r
-    DialogWindow::LaunchOptions o;\r
-    o.content.setNonOwned (&audioSettingsComp);\r
-    o.dialogTitle                   = "Audio Settings";\r
-    o.componentToCentreAround       = this;\r
-    o.dialogBackgroundColour        = getLookAndFeel().findColour (ResizableWindow::backgroundColourId);\r
-    o.escapeKeyTriggersCloseButton  = true;\r
-    o.useNativeTitleBar             = false;\r
-    o.resizable                     = false;\r
-\r
-    o.runModal();\r
-\r
-    ScopedPointer<XmlElement> audioState (deviceManager.createStateXml());\r
-\r
-    getAppProperties().getUserSettings()->setValue ("audioDeviceState", audioState);\r
-    getAppProperties().getUserSettings()->saveIfNeeded();\r
-\r
-    if (graphHolder != nullptr)\r
-        if (graphHolder->graph != nullptr)\r
-            graphHolder->graph->graph.removeIllegalConnections();\r
-}\r
-\r
-bool MainHostWindow::isInterestedInFileDrag (const StringArray&)\r
-{\r
-    return true;\r
-}\r
-\r
-void MainHostWindow::fileDragEnter (const StringArray&, int, int)\r
-{\r
-}\r
-\r
-void MainHostWindow::fileDragMove (const StringArray&, int, int)\r
-{\r
-}\r
-\r
-void MainHostWindow::fileDragExit (const StringArray&)\r
-{\r
-}\r
-\r
-void MainHostWindow::filesDropped (const StringArray& files, int x, int y)\r
-{\r
-    if (graphHolder != nullptr)\r
-    {\r
-        if (files.size() == 1 && File (files[0]).hasFileExtension (FilterGraph::getFilenameSuffix()))\r
-        {\r
-            if (auto* filterGraph = graphHolder->graph.get())\r
-                if (filterGraph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)\r
-                    filterGraph->loadFrom (File (files[0]), true);\r
-        }\r
-        else\r
-        {\r
-            OwnedArray<PluginDescription> typesFound;\r
-            knownPluginList.scanAndAddDragAndDroppedFiles (formatManager, files, typesFound);\r
-\r
-            auto pos = graphHolder->getLocalPoint (this, Point<int> (x, y));\r
-\r
-            for (int i = 0; i < jmin (5, typesFound.size()); ++i)\r
-                if (auto* desc = typesFound.getUnchecked(i))\r
-                    createPlugin (*desc, pos);\r
-        }\r
-    }\r
-}\r
-\r
-bool MainHostWindow::isDoublePrecisionProcessing()\r
-{\r
-    if (auto* props = getAppProperties().getUserSettings())\r
-        return props->getBoolValue ("doublePrecisionProcessing", false);\r
-\r
-    return false;\r
-}\r
-\r
-void MainHostWindow::updatePrecisionMenuItem (ApplicationCommandInfo& info)\r
-{\r
-    info.setInfo ("Double floating point precision rendering", String(), "General", 0);\r
-    info.setTicked (isDoublePrecisionProcessing());\r
-}\r
diff --git a/extras/AudioPluginHost/Source/MainHostWindow.h b/extras/AudioPluginHost/Source/MainHostWindow.h
deleted file mode 100644 (file)
index f254d7c..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*\r
-  ==============================================================================\r
-\r
-   This file is part of the JUCE library.\r
-   Copyright (c) 2017 - ROLI Ltd.\r
-\r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
-   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
-   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
-   27th April 2017).\r
-\r
-   End User License Agreement: www.juce.com/juce-5-licence\r
-   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
-   Or: You may also use this code under the terms of the GPL v3 (see\r
-   www.gnu.org/licenses).\r
-\r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
-\r
-  ==============================================================================\r
-*/\r
-\r
-#pragma once\r
-\r
-#include "FilterGraph.h"\r
-#include "GraphEditorPanel.h"\r
-\r
-\r
-//==============================================================================\r
-namespace CommandIDs\r
-{\r
-    static const int open                   = 0x30000;\r
-    static const int save                   = 0x30001;\r
-    static const int saveAs                 = 0x30002;\r
-    static const int newFile                = 0x30003;\r
-    static const int showPluginListEditor   = 0x30100;\r
-    static const int showAudioSettings      = 0x30200;\r
-    static const int aboutBox               = 0x30300;\r
-    static const int allWindowsForward      = 0x30400;\r
-    static const int toggleDoublePrecision  = 0x30500;\r
-}\r
-\r
-ApplicationCommandManager& getCommandManager();\r
-ApplicationProperties& getAppProperties();\r
-\r
-//==============================================================================\r
-class MainHostWindow    : public DocumentWindow,\r
-                          public MenuBarModel,\r
-                          public ApplicationCommandTarget,\r
-                          public ChangeListener,\r
-                          public FileDragAndDropTarget\r
-{\r
-public:\r
-    //==============================================================================\r
-    MainHostWindow();\r
-    ~MainHostWindow();\r
-\r
-    //==============================================================================\r
-    void closeButtonPressed() override;\r
-    void changeListenerCallback (ChangeBroadcaster*) override;\r
-\r
-    bool isInterestedInFileDrag (const StringArray& files) override;\r
-    void fileDragEnter (const StringArray& files, int, int) override;\r
-    void fileDragMove (const StringArray& files, int, int) override;\r
-    void fileDragExit (const StringArray& files) override;\r
-    void filesDropped (const StringArray& files, int, int) override;\r
-\r
-    void menuBarActivated (bool isActive) override;\r
-\r
-    StringArray getMenuBarNames() override;\r
-    PopupMenu getMenuForIndex (int topLevelMenuIndex, const String& menuName) override;\r
-    void menuItemSelected (int menuItemID, int topLevelMenuIndex) override;\r
-    ApplicationCommandTarget* getNextCommandTarget() override;\r
-    void getAllCommands (Array<CommandID>&) override;\r
-    void getCommandInfo (CommandID, ApplicationCommandInfo&) override;\r
-    bool perform (const InvocationInfo&) override;\r
-\r
-    void tryToQuitApplication();\r
-\r
-    void createPlugin (const PluginDescription&, Point<int> pos);\r
-\r
-    void addPluginsToMenu (PopupMenu&) const;\r
-    const PluginDescription* getChosenType (int menuID) const;\r
-\r
-    bool isDoublePrecisionProcessing();\r
-    void updatePrecisionMenuItem (ApplicationCommandInfo& info);\r
-\r
-    ScopedPointer<GraphDocumentComponent> graphHolder;\r
-\r
-private:\r
-    //==============================================================================\r
-    AudioDeviceManager deviceManager;\r
-    AudioPluginFormatManager formatManager;\r
-\r
-    OwnedArray<PluginDescription> internalTypes;\r
-    KnownPluginList knownPluginList;\r
-    KnownPluginList::SortMethod pluginSortMethod;\r
-\r
-    class PluginListWindow;\r
-    ScopedPointer<PluginListWindow> pluginListWindow;\r
-\r
-    void showAudioSettings();\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainHostWindow)\r
-};\r
diff --git a/extras/AudioPluginHost/Source/PluginWindow.h b/extras/AudioPluginHost/Source/PluginWindow.h
deleted file mode 100644 (file)
index 88b7174..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/*\r
-  ==============================================================================\r
-\r
-   This file is part of the JUCE library.\r
-   Copyright (c) 2017 - ROLI Ltd.\r
-\r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
-   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
-   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
-   27th April 2017).\r
-\r
-   End User License Agreement: www.juce.com/juce-5-licence\r
-   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
-   Or: You may also use this code under the terms of the GPL v3 (see\r
-   www.gnu.org/licenses).\r
-\r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
-\r
-  ==============================================================================\r
-*/\r
-\r
-#pragma once\r
-\r
-#include "FilterIOConfiguration.h"\r
-class FilterGraph;\r
-\r
-//==============================================================================\r
-/**\r
-    A desktop window containing a plugin's GUI.\r
-*/\r
-class PluginWindow  : public DocumentWindow\r
-{\r
-public:\r
-    enum class Type\r
-    {\r
-        normal = 0,\r
-        generic,\r
-        programs,\r
-        audioIO,\r
-        numTypes\r
-    };\r
-\r
-    PluginWindow (AudioProcessorGraph::Node* n, Type t, OwnedArray<PluginWindow>& windowList)\r
-       : DocumentWindow (n->getProcessor()->getName(),\r
-                         LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),\r
-                         DocumentWindow::minimiseButton | DocumentWindow::closeButton),\r
-         activeWindowList (windowList),\r
-         node (n), type (t)\r
-    {\r
-        setSize (400, 300);\r
-\r
-        if (auto* ui = createProcessorEditor (*node->getProcessor(), type))\r
-            setContentOwned (ui, true);\r
-\r
-        setTopLeftPosition (node->properties.getWithDefault (getLastXProp (type), Random::getSystemRandom().nextInt (500)),\r
-                            node->properties.getWithDefault (getLastYProp (type), Random::getSystemRandom().nextInt (500)));\r
-\r
-        node->properties.set (getOpenProp (type), true);\r
-\r
-        setVisible (true);\r
-    }\r
-\r
-    ~PluginWindow()\r
-    {\r
-        clearContentComponent();\r
-    }\r
-\r
-    void moved() override\r
-    {\r
-        node->properties.set (getLastXProp (type), getX());\r
-        node->properties.set (getLastYProp (type), getY());\r
-    }\r
-\r
-    void closeButtonPressed() override\r
-    {\r
-        node->properties.set (getOpenProp (type), false);\r
-        activeWindowList.removeObject (this);\r
-    }\r
-\r
-    static String getLastXProp (Type type)    { return "uiLastX_" + getTypeName (type); }\r
-    static String getLastYProp (Type type)    { return "uiLastY_" + getTypeName (type); }\r
-    static String getOpenProp  (Type type)    { return "uiopen_"  + getTypeName (type); }\r
-\r
-    OwnedArray<PluginWindow>& activeWindowList;\r
-    const AudioProcessorGraph::Node::Ptr node;\r
-    const Type type;\r
-\r
-private:\r
-    float getDesktopScaleFactor() const override     { return 1.0f; }\r
-\r
-    static AudioProcessorEditor* createProcessorEditor (AudioProcessor& processor, PluginWindow::Type type)\r
-    {\r
-        if (type == PluginWindow::Type::normal)\r
-        {\r
-            if (auto* ui = processor.createEditorIfNeeded())\r
-                return ui;\r
-\r
-            type = PluginWindow::Type::generic;\r
-        }\r
-\r
-        if (type == PluginWindow::Type::generic)\r
-            return new GenericAudioProcessorEditor (&processor);\r
-\r
-        if (type == PluginWindow::Type::programs)\r
-            return new ProgramAudioProcessorEditor (processor);\r
-\r
-        if (type == PluginWindow::Type::audioIO)\r
-            return new FilterIOConfigurationWindow (processor);\r
-\r
-        jassertfalse;\r
-        return {};\r
-    }\r
-\r
-    static String getTypeName (Type type)\r
-    {\r
-        switch (type)\r
-        {\r
-            case Type::normal:     return "Normal";\r
-            case Type::generic:    return "Generic";\r
-            case Type::programs:   return "Programs";\r
-            case Type::audioIO:    return "IO";\r
-            default:               return {};\r
-        }\r
-    }\r
-\r
-    //==============================================================================\r
-    struct ProgramAudioProcessorEditor  : public AudioProcessorEditor\r
-    {\r
-        ProgramAudioProcessorEditor (AudioProcessor& p)  : AudioProcessorEditor (p)\r
-        {\r
-            setOpaque (true);\r
-\r
-            addAndMakeVisible (panel);\r
-\r
-            Array<PropertyComponent*> programs;\r
-\r
-            auto numPrograms = p.getNumPrograms();\r
-            int totalHeight = 0;\r
-\r
-            for (int i = 0; i < numPrograms; ++i)\r
-            {\r
-                auto name = p.getProgramName (i).trim();\r
-\r
-                if (name.isEmpty())\r
-                    name = "Unnamed";\r
-\r
-                auto pc = new PropertyComp (name, p);\r
-                programs.add (pc);\r
-                totalHeight += pc->getPreferredHeight();\r
-            }\r
-\r
-            panel.addProperties (programs);\r
-\r
-            setSize (400, jlimit (25, 400, totalHeight));\r
-        }\r
-\r
-        void paint (Graphics& g) override\r
-        {\r
-            g.fillAll (Colours::grey);\r
-        }\r
-\r
-        void resized() override\r
-        {\r
-            panel.setBounds (getLocalBounds());\r
-        }\r
-\r
-    private:\r
-        struct PropertyComp  : public PropertyComponent,\r
-                               private AudioProcessorListener\r
-        {\r
-            PropertyComp (const String& name, AudioProcessor& p)  : PropertyComponent (name), owner (p)\r
-            {\r
-                owner.addListener (this);\r
-            }\r
-\r
-            ~PropertyComp()\r
-            {\r
-                owner.removeListener (this);\r
-            }\r
-\r
-            void refresh() override {}\r
-            void audioProcessorChanged (AudioProcessor*) override {}\r
-            void audioProcessorParameterChanged (AudioProcessor*, int, float) override {}\r
-\r
-            AudioProcessor& owner;\r
-\r
-            JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertyComp)\r
-        };\r
-\r
-        PropertyPanel panel;\r
-\r
-        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgramAudioProcessorEditor)\r
-    };\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginWindow)\r
-};\r
diff --git a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp
new file mode 100644 (file)
index 0000000..dfd8155
--- /dev/null
@@ -0,0 +1,1306 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#include "../JuceLibraryCode/JuceHeader.h"\r
+#include "GraphEditorPanel.h"\r
+#include "../Filters/InternalFilters.h"\r
+#include "MainHostWindow.h"\r
+\r
+//==============================================================================\r
+#if JUCE_IOS\r
+ class AUScanner\r
+ {\r
+ public:\r
+     AUScanner (KnownPluginList& list)\r
+         : knownPluginList (list), pool (5)\r
+     {\r
+         knownPluginList.clearBlacklistedFiles();\r
+         paths = formatToScan.getDefaultLocationsToSearch();\r
+\r
+         startScan();\r
+     }\r
+\r
+ private:\r
+     KnownPluginList& knownPluginList;\r
+     AudioUnitPluginFormat formatToScan;\r
+\r
+     ScopedPointer<PluginDirectoryScanner> scanner;\r
+     FileSearchPath paths;\r
+\r
+     ThreadPool pool;\r
+\r
+     void startScan()\r
+     {\r
+         auto deadMansPedalFile = getAppProperties().getUserSettings()\r
+                                     ->getFile().getSiblingFile ("RecentlyCrashedPluginsList");\r
+\r
+         scanner = new PluginDirectoryScanner (knownPluginList, formatToScan, paths,\r
+                                               true, deadMansPedalFile, true);\r
+\r
+         for (int i = 5; --i >= 0;)\r
+             pool.addJob (new ScanJob (*this), true);\r
+     }\r
+\r
+     bool doNextScan()\r
+     {\r
+         String pluginBeingScanned;\r
+         if (scanner->scanNextFile (true, pluginBeingScanned))\r
+             return true;\r
+\r
+         return false;\r
+     }\r
+\r
+     struct ScanJob  : public ThreadPoolJob\r
+     {\r
+         ScanJob (AUScanner& s)  : ThreadPoolJob ("pluginscan"), scanner (s) {}\r
+\r
+         JobStatus runJob()\r
+         {\r
+             while (scanner.doNextScan() && ! shouldExit())\r
+             {}\r
+\r
+             return jobHasFinished;\r
+         }\r
+\r
+         AUScanner& scanner;\r
+\r
+         JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScanJob)\r
+     };\r
+\r
+     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AUScanner)\r
+ };\r
+#endif\r
+\r
+//==============================================================================\r
+struct GraphEditorPanel::PinComponent   : public Component,\r
+                                          public SettableTooltipClient\r
+{\r
+    PinComponent (GraphEditorPanel& p, AudioProcessorGraph::NodeAndChannel pinToUse, bool isIn)\r
+        : panel (p), graph (p.graph), pin (pinToUse), isInput (isIn)\r
+    {\r
+        if (auto node = graph.graph.getNodeForId (pin.nodeID))\r
+        {\r
+            String tip;\r
+\r
+            if (pin.isMIDI())\r
+            {\r
+                tip = isInput ? "MIDI Input"\r
+                              : "MIDI Output";\r
+            }\r
+            else\r
+            {\r
+                auto& processor = *node->getProcessor();\r
+                auto channel = processor.getOffsetInBusBufferForAbsoluteChannelIndex (isInput, pin.channelIndex, busIdx);\r
+\r
+                if (auto* bus = processor.getBus (isInput, busIdx))\r
+                    tip = bus->getName() + ": " + AudioChannelSet::getAbbreviatedChannelTypeName (bus->getCurrentLayout().getTypeOfChannel (channel));\r
+                else\r
+                    tip = (isInput ? "Main Input: "\r
+                                   : "Main Output: ") + String (pin.channelIndex + 1);\r
+\r
+            }\r
+\r
+            setTooltip (tip);\r
+        }\r
+\r
+        setSize (16, 16);\r
+    }\r
+\r
+    void paint (Graphics& g) override\r
+    {\r
+        auto w = (float) getWidth();\r
+        auto h = (float) getHeight();\r
+\r
+        Path p;\r
+        p.addEllipse (w * 0.25f, h * 0.25f, w * 0.5f, h * 0.5f);\r
+        p.addRectangle (w * 0.4f, isInput ? (0.5f * h) : 0.0f, w * 0.2f, h * 0.5f);\r
+\r
+        auto colour = (pin.isMIDI() ? Colours::red : Colours::green);\r
+\r
+        g.setColour (colour.withRotatedHue (busIdx / 5.0f));\r
+        g.fillPath (p);\r
+    }\r
+\r
+    void mouseDown (const MouseEvent& e) override\r
+    {\r
+        AudioProcessorGraph::NodeAndChannel dummy { 0, 0 };\r
+\r
+        panel.beginConnectorDrag (isInput ? dummy : pin,\r
+                                  isInput ? pin : dummy,\r
+                                  e);\r
+    }\r
+\r
+    void mouseDrag (const MouseEvent& e) override\r
+    {\r
+        panel.dragConnector (e);\r
+    }\r
+\r
+    void mouseUp (const MouseEvent& e) override\r
+    {\r
+        panel.endDraggingConnector (e);\r
+    }\r
+\r
+    GraphEditorPanel& panel;\r
+    FilterGraph& graph;\r
+    AudioProcessorGraph::NodeAndChannel pin;\r
+    const bool isInput;\r
+    int busIdx = 0;\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PinComponent)\r
+};\r
+\r
+//==============================================================================\r
+struct GraphEditorPanel::FilterComponent   : public Component,\r
+                                             public Timer,\r
+                                             private AudioProcessorParameter::Listener\r
+{\r
+    FilterComponent (GraphEditorPanel& p, uint32 id)  : panel (p), graph (p.graph), pluginID (id)\r
+    {\r
+        shadow.setShadowProperties (DropShadow (Colours::black.withAlpha (0.5f), 3, { 0, 1 }));\r
+        setComponentEffect (&shadow);\r
+\r
+        if (auto f = graph.graph.getNodeForId (pluginID))\r
+        {\r
+            if (auto* processor = f->getProcessor())\r
+            {\r
+                if (auto* bypassParam = processor->getBypassParameter())\r
+                    bypassParam->addListener (this);\r
+            }\r
+        }\r
+\r
+        setSize (150, 60);\r
+    }\r
+\r
+    FilterComponent (const FilterComponent&) = delete;\r
+    FilterComponent& operator= (const FilterComponent&) = delete;\r
+\r
+    ~FilterComponent()\r
+    {\r
+        if (auto f = graph.graph.getNodeForId (pluginID))\r
+        {\r
+            if (auto* processor = f->getProcessor())\r
+            {\r
+                if (auto* bypassParam = processor->getBypassParameter())\r
+                    bypassParam->removeListener (this);\r
+            }\r
+        }\r
+    }\r
+\r
+    void mouseDown (const MouseEvent& e) override\r
+    {\r
+        originalPos = localPointToGlobal (Point<int>());\r
+\r
+        toFront (true);\r
+\r
+        if (isOnTouchDevice())\r
+        {\r
+            startTimer (750);\r
+        }\r
+        else\r
+        {\r
+            if (e.mods.isPopupMenu())\r
+                showPopupMenu();\r
+        }\r
+    }\r
+\r
+    void mouseDrag (const MouseEvent& e) override\r
+    {\r
+        if (isOnTouchDevice() && e.getDistanceFromDragStart() > 5)\r
+            stopTimer();\r
+\r
+        if (! e.mods.isPopupMenu())\r
+        {\r
+            auto pos = originalPos + e.getOffsetFromDragStart();\r
+\r
+            if (getParentComponent() != nullptr)\r
+                pos = getParentComponent()->getLocalPoint (nullptr, pos);\r
+\r
+            pos += getLocalBounds().getCentre();\r
+\r
+            graph.setNodePosition (pluginID,\r
+                                   { pos.x / (double) getParentWidth(),\r
+                                     pos.y / (double) getParentHeight() });\r
+\r
+            panel.updateComponents();\r
+        }\r
+    }\r
+\r
+    void mouseUp (const MouseEvent& e) override\r
+    {\r
+        if (isOnTouchDevice())\r
+        {\r
+            stopTimer();\r
+            callAfterDelay (250, []() { PopupMenu::dismissAllActiveMenus(); });\r
+        }\r
+\r
+        if (e.mouseWasDraggedSinceMouseDown())\r
+        {\r
+            graph.setChangedFlag (true);\r
+        }\r
+        else if (e.getNumberOfClicks() == 2)\r
+        {\r
+            if (auto f = graph.graph.getNodeForId (pluginID))\r
+                if (auto* w = graph.getOrCreateWindowFor (f, PluginWindow::Type::normal))\r
+                    w->toFront (true);\r
+        }\r
+    }\r
+\r
+    bool hitTest (int x, int y) override\r
+    {\r
+        for (auto* child : getChildren())\r
+            if (child->getBounds().contains (x, y))\r
+                return true;\r
+\r
+        return x >= 3 && x < getWidth() - 6 && y >= pinSize && y < getHeight() - pinSize;\r
+    }\r
+\r
+    void paint (Graphics& g) override\r
+    {\r
+        auto boxArea = getLocalBounds().reduced (4, pinSize);\r
+        bool isBypassed = false;\r
+\r
+        if (auto* f = graph.graph.getNodeForId (pluginID))\r
+            isBypassed = f->isBypassed();\r
+\r
+        auto boxColour = findColour (TextEditor::backgroundColourId);\r
+\r
+        if (isBypassed)\r
+            boxColour = boxColour.brighter();\r
+\r
+        g.setColour (boxColour);\r
+        g.fillRect (boxArea.toFloat());\r
+\r
+        g.setColour (findColour (TextEditor::textColourId));\r
+        g.setFont (font);\r
+        g.drawFittedText (getName(), boxArea, Justification::centred, 2);\r
+    }\r
+\r
+    void resized() override\r
+    {\r
+        if (auto f = graph.graph.getNodeForId (pluginID))\r
+        {\r
+            if (auto* processor = f->getProcessor())\r
+            {\r
+                for (auto* pin : pins)\r
+                {\r
+                    const bool isInput = pin->isInput;\r
+                    auto channelIndex = pin->pin.channelIndex;\r
+                    int busIdx = 0;\r
+                    processor->getOffsetInBusBufferForAbsoluteChannelIndex (isInput, channelIndex, busIdx);\r
+\r
+                    const int total = isInput ? numIns : numOuts;\r
+                    const int index = pin->pin.isMIDI() ? (total - 1) : channelIndex;\r
+\r
+                    auto totalSpaces = static_cast<float> (total) + (static_cast<float> (jmax (0, processor->getBusCount (isInput) - 1)) * 0.5f);\r
+                    auto indexPos = static_cast<float> (index) + (static_cast<float> (busIdx) * 0.5f);\r
+\r
+                    pin->setBounds (proportionOfWidth ((1.0f + indexPos) / (totalSpaces + 1.0f)) - pinSize / 2,\r
+                                    pin->isInput ? 0 : (getHeight() - pinSize),\r
+                                    pinSize, pinSize);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    Point<float> getPinPos (int index, bool isInput) const\r
+    {\r
+        for (auto* pin : pins)\r
+            if (pin->pin.channelIndex == index && isInput == pin->isInput)\r
+                return getPosition().toFloat() + pin->getBounds().getCentre().toFloat();\r
+\r
+        return {};\r
+    }\r
+\r
+    void update()\r
+    {\r
+        const AudioProcessorGraph::Node::Ptr f (graph.graph.getNodeForId (pluginID));\r
+        jassert (f != nullptr);\r
+\r
+        numIns = f->getProcessor()->getTotalNumInputChannels();\r
+        if (f->getProcessor()->acceptsMidi())\r
+            ++numIns;\r
+\r
+        numOuts = f->getProcessor()->getTotalNumOutputChannels();\r
+        if (f->getProcessor()->producesMidi())\r
+            ++numOuts;\r
+\r
+        int w = 100;\r
+        int h = 60;\r
+\r
+        w = jmax (w, (jmax (numIns, numOuts) + 1) * 20);\r
+\r
+        const int textWidth = font.getStringWidth (f->getProcessor()->getName());\r
+        w = jmax (w, 16 + jmin (textWidth, 300));\r
+        if (textWidth > 300)\r
+            h = 100;\r
+\r
+        setSize (w, h);\r
+\r
+        setName (f->getProcessor()->getName());\r
+\r
+        {\r
+            auto p = graph.getNodePosition (pluginID);\r
+            setCentreRelative ((float) p.x, (float) p.y);\r
+        }\r
+\r
+        if (numIns != numInputs || numOuts != numOutputs)\r
+        {\r
+            numInputs = numIns;\r
+            numOutputs = numOuts;\r
+\r
+            pins.clear();\r
+\r
+            for (int i = 0; i < f->getProcessor()->getTotalNumInputChannels(); ++i)\r
+                addAndMakeVisible (pins.add (new PinComponent (panel, { pluginID, i }, true)));\r
+\r
+            if (f->getProcessor()->acceptsMidi())\r
+                addAndMakeVisible (pins.add (new PinComponent (panel, { pluginID, AudioProcessorGraph::midiChannelIndex }, true)));\r
+\r
+            for (int i = 0; i < f->getProcessor()->getTotalNumOutputChannels(); ++i)\r
+                addAndMakeVisible (pins.add (new PinComponent (panel, { pluginID, i }, false)));\r
+\r
+            if (f->getProcessor()->producesMidi())\r
+                addAndMakeVisible (pins.add (new PinComponent (panel, { pluginID, AudioProcessorGraph::midiChannelIndex }, false)));\r
+\r
+            resized();\r
+        }\r
+    }\r
+\r
+    AudioProcessor* getProcessor() const\r
+    {\r
+        if (auto node = graph.graph.getNodeForId (pluginID))\r
+            return node->getProcessor();\r
+\r
+        return {};\r
+    }\r
+\r
+    void showPopupMenu()\r
+    {\r
+        menu = new PopupMenu;\r
+        menu->addItem (1, "Delete this filter");\r
+        menu->addItem (2, "Disconnect all pins");\r
+        menu->addItem (3, "Toggle Bypass");\r
+\r
+        if (getProcessor()->hasEditor())\r
+        {\r
+            menu->addSeparator();\r
+            menu->addItem (10, "Show plugin GUI");\r
+            menu->addItem (11, "Show all programs");\r
+            menu->addItem (12, "Show all parameters");\r
+        }\r
+\r
+        menu->addSeparator();\r
+        menu->addItem (20, "Configure Audio I/O");\r
+        menu->addItem (21, "Test state save/load");\r
+\r
+        menu->showMenuAsync ({}, ModalCallbackFunction::create\r
+                             ([this] (int r) {\r
+        switch (r)\r
+        {\r
+            case 1:   graph.graph.removeNode (pluginID); break;\r
+            case 2:   graph.graph.disconnectNode (pluginID); break;\r
+            case 3:\r
+            {\r
+                if (auto* node = graph.graph.getNodeForId (pluginID))\r
+                    node->setBypassed (! node->isBypassed());\r
+\r
+                repaint();\r
+\r
+                break;\r
+            }\r
+            case 10:  showWindow (PluginWindow::Type::normal); break;\r
+            case 11:  showWindow (PluginWindow::Type::programs); break;\r
+            case 12:  showWindow (PluginWindow::Type::generic); break;\r
+            case 20:  showWindow (PluginWindow::Type::audioIO); break;\r
+            case 21:  testStateSaveLoad(); break;\r
+\r
+            default:  break;\r
+        }\r
+        }));\r
+    }\r
+\r
+    void testStateSaveLoad()\r
+    {\r
+        if (auto* processor = getProcessor())\r
+        {\r
+            MemoryBlock state;\r
+            processor->getStateInformation (state);\r
+            processor->setStateInformation (state.getData(), (int) state.getSize());\r
+        }\r
+    }\r
+\r
+    void showWindow (PluginWindow::Type type)\r
+    {\r
+        if (auto node = graph.graph.getNodeForId (pluginID))\r
+            if (auto* w = graph.getOrCreateWindowFor (node, type))\r
+                w->toFront (true);\r
+    }\r
+\r
+    void timerCallback() override\r
+    {\r
+        // this should only be called on touch devices\r
+        jassert (isOnTouchDevice());\r
+\r
+        stopTimer();\r
+        showPopupMenu();\r
+    }\r
+\r
+    void parameterValueChanged (int, float) override\r
+    {\r
+        repaint();\r
+    }\r
+\r
+    void parameterGestureChanged (int, bool) override  {}\r
+\r
+    GraphEditorPanel& panel;\r
+    FilterGraph& graph;\r
+    const AudioProcessorGraph::NodeID pluginID;\r
+    OwnedArray<PinComponent> pins;\r
+    int numInputs = 0, numOutputs = 0;\r
+    int pinSize = 16;\r
+    Point<int> originalPos;\r
+    Font font { 13.0f, Font::bold };\r
+    int numIns = 0, numOuts = 0;\r
+    DropShadowEffect shadow;\r
+    ScopedPointer<PopupMenu> menu;\r
+};\r
+\r
+\r
+//==============================================================================\r
+struct GraphEditorPanel::ConnectorComponent   : public Component,\r
+                                                public SettableTooltipClient\r
+{\r
+    ConnectorComponent (GraphEditorPanel& p) : panel (p), graph (p.graph)\r
+    {\r
+        setAlwaysOnTop (true);\r
+    }\r
+\r
+    void setInput (AudioProcessorGraph::NodeAndChannel newSource)\r
+    {\r
+        if (connection.source != newSource)\r
+        {\r
+            connection.source = newSource;\r
+            update();\r
+        }\r
+    }\r
+\r
+    void setOutput (AudioProcessorGraph::NodeAndChannel newDest)\r
+    {\r
+        if (connection.destination != newDest)\r
+        {\r
+            connection.destination = newDest;\r
+            update();\r
+        }\r
+    }\r
+\r
+    void dragStart (Point<float> pos)\r
+    {\r
+        lastInputPos = pos;\r
+        resizeToFit();\r
+    }\r
+\r
+    void dragEnd (Point<float> pos)\r
+    {\r
+        lastOutputPos = pos;\r
+        resizeToFit();\r
+    }\r
+\r
+    void update()\r
+    {\r
+        Point<float> p1, p2;\r
+        getPoints (p1, p2);\r
+\r
+        if (lastInputPos != p1 || lastOutputPos != p2)\r
+            resizeToFit();\r
+    }\r
+\r
+    void resizeToFit()\r
+    {\r
+        Point<float> p1, p2;\r
+        getPoints (p1, p2);\r
+\r
+        auto newBounds = Rectangle<float> (p1, p2).expanded (4.0f).getSmallestIntegerContainer();\r
+\r
+        if (newBounds != getBounds())\r
+            setBounds (newBounds);\r
+        else\r
+            resized();\r
+\r
+        repaint();\r
+    }\r
+\r
+    void getPoints (Point<float>& p1, Point<float>& p2) const\r
+    {\r
+        p1 = lastInputPos;\r
+        p2 = lastOutputPos;\r
+\r
+        if (auto* src = panel.getComponentForFilter (connection.source.nodeID))\r
+            p1 = src->getPinPos (connection.source.channelIndex, false);\r
+\r
+        if (auto* dest = panel.getComponentForFilter (connection.destination.nodeID))\r
+            p2 = dest->getPinPos (connection.destination.channelIndex, true);\r
+    }\r
+\r
+    void paint (Graphics& g) override\r
+    {\r
+        if (connection.source.isMIDI() || connection.destination.isMIDI())\r
+            g.setColour (Colours::red);\r
+        else\r
+            g.setColour (Colours::green);\r
+\r
+        g.fillPath (linePath);\r
+    }\r
+\r
+    bool hitTest (int x, int y) override\r
+    {\r
+        auto pos = Point<int> (x, y).toFloat();\r
+\r
+        if (hitPath.contains (pos))\r
+        {\r
+            double distanceFromStart, distanceFromEnd;\r
+            getDistancesFromEnds (pos, distanceFromStart, distanceFromEnd);\r
+\r
+            // avoid clicking the connector when over a pin\r
+            return distanceFromStart > 7.0 && distanceFromEnd > 7.0;\r
+        }\r
+\r
+        return false;\r
+    }\r
+\r
+    void mouseDown (const MouseEvent&) override\r
+    {\r
+        dragging = false;\r
+    }\r
+\r
+    void mouseDrag (const MouseEvent& e) override\r
+    {\r
+        if (dragging)\r
+        {\r
+            panel.dragConnector (e);\r
+        }\r
+        else if (e.mouseWasDraggedSinceMouseDown())\r
+        {\r
+            dragging = true;\r
+\r
+            graph.graph.removeConnection (connection);\r
+\r
+            double distanceFromStart, distanceFromEnd;\r
+            getDistancesFromEnds (getPosition().toFloat() + e.position, distanceFromStart, distanceFromEnd);\r
+            const bool isNearerSource = (distanceFromStart < distanceFromEnd);\r
+\r
+            AudioProcessorGraph::NodeAndChannel dummy { 0, 0 };\r
+\r
+            panel.beginConnectorDrag (isNearerSource ? dummy : connection.source,\r
+                                      isNearerSource ? connection.destination : dummy,\r
+                                      e);\r
+        }\r
+    }\r
+\r
+    void mouseUp (const MouseEvent& e) override\r
+    {\r
+        if (dragging)\r
+            panel.endDraggingConnector (e);\r
+    }\r
+\r
+    void resized() override\r
+    {\r
+        Point<float> p1, p2;\r
+        getPoints (p1, p2);\r
+\r
+        lastInputPos = p1;\r
+        lastOutputPos = p2;\r
+\r
+        p1 -= getPosition().toFloat();\r
+        p2 -= getPosition().toFloat();\r
+\r
+        linePath.clear();\r
+        linePath.startNewSubPath (p1);\r
+        linePath.cubicTo (p1.x, p1.y + (p2.y - p1.y) * 0.33f,\r
+                          p2.x, p1.y + (p2.y - p1.y) * 0.66f,\r
+                          p2.x, p2.y);\r
+\r
+        PathStrokeType wideStroke (8.0f);\r
+        wideStroke.createStrokedPath (hitPath, linePath);\r
+\r
+        PathStrokeType stroke (2.5f);\r
+        stroke.createStrokedPath (linePath, linePath);\r
+\r
+        auto arrowW = 5.0f;\r
+        auto arrowL = 4.0f;\r
+\r
+        Path arrow;\r
+        arrow.addTriangle (-arrowL, arrowW,\r
+                           -arrowL, -arrowW,\r
+                           arrowL, 0.0f);\r
+\r
+        arrow.applyTransform (AffineTransform()\r
+                                .rotated (MathConstants<float>::halfPi - (float) atan2 (p2.x - p1.x, p2.y - p1.y))\r
+                                .translated ((p1 + p2) * 0.5f));\r
+\r
+        linePath.addPath (arrow);\r
+        linePath.setUsingNonZeroWinding (true);\r
+    }\r
+\r
+    void getDistancesFromEnds (Point<float> p, double& distanceFromStart, double& distanceFromEnd) const\r
+    {\r
+        Point<float> p1, p2;\r
+        getPoints (p1, p2);\r
+\r
+        distanceFromStart = p1.getDistanceFrom (p);\r
+        distanceFromEnd   = p2.getDistanceFrom (p);\r
+    }\r
+\r
+    GraphEditorPanel& panel;\r
+    FilterGraph& graph;\r
+    AudioProcessorGraph::Connection connection { { 0, 0 }, { 0, 0 } };\r
+    Point<float> lastInputPos, lastOutputPos;\r
+    Path linePath, hitPath;\r
+    bool dragging = false;\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectorComponent)\r
+};\r
+\r
+\r
+//==============================================================================\r
+GraphEditorPanel::GraphEditorPanel (FilterGraph& g)  : graph (g)\r
+{\r
+    graph.addChangeListener (this);\r
+    setOpaque (true);\r
+}\r
+\r
+GraphEditorPanel::~GraphEditorPanel()\r
+{\r
+    graph.removeChangeListener (this);\r
+    draggingConnector = nullptr;\r
+    nodes.clear();\r
+    connectors.clear();\r
+}\r
+\r
+void GraphEditorPanel::paint (Graphics& g)\r
+{\r
+    g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r
+}\r
+\r
+void GraphEditorPanel::mouseDown (const MouseEvent& e)\r
+{\r
+    if (isOnTouchDevice())\r
+    {\r
+        originalTouchPos = e.position.toInt();\r
+        startTimer (750);\r
+    }\r
+\r
+    if (e.mods.isPopupMenu())\r
+        showPopupMenu (e.position.toInt());\r
+}\r
+\r
+void GraphEditorPanel::mouseUp (const MouseEvent&)\r
+{\r
+    if (isOnTouchDevice())\r
+    {\r
+        stopTimer();\r
+        callAfterDelay (250, []() { PopupMenu::dismissAllActiveMenus(); });\r
+    }\r
+}\r
+\r
+void GraphEditorPanel::mouseDrag (const MouseEvent& e)\r
+{\r
+    if (isOnTouchDevice() && e.getDistanceFromDragStart() > 5)\r
+        stopTimer();\r
+}\r
+\r
+void GraphEditorPanel::createNewPlugin (const PluginDescription& desc, Point<int> position)\r
+{\r
+    graph.addPlugin (desc, position.toDouble() / Point<double> ((double) getWidth(), (double) getHeight()));\r
+}\r
+\r
+GraphEditorPanel::FilterComponent* GraphEditorPanel::getComponentForFilter (const uint32 filterID) const\r
+{\r
+    for (auto* fc : nodes)\r
+       if (fc->pluginID == filterID)\r
+            return fc;\r
+\r
+    return nullptr;\r
+}\r
+\r
+GraphEditorPanel::ConnectorComponent* GraphEditorPanel::getComponentForConnection (const AudioProcessorGraph::Connection& conn) const\r
+{\r
+    for (auto* cc : connectors)\r
+        if (cc->connection == conn)\r
+            return cc;\r
+\r
+    return nullptr;\r
+}\r
+\r
+GraphEditorPanel::PinComponent* GraphEditorPanel::findPinAt (Point<float> pos) const\r
+{\r
+    for (auto* fc : nodes)\r
+    {\r
+        // NB: A Visual Studio optimiser error means we have to put this Component* in a local\r
+        // variable before trying to cast it, or it gets mysteriously optimised away..\r
+        auto* comp = fc->getComponentAt (pos.toInt() - fc->getPosition());\r
+\r
+        if (auto* pin = dynamic_cast<PinComponent*> (comp))\r
+            return pin;\r
+    }\r
+\r
+    return nullptr;\r
+}\r
+\r
+void GraphEditorPanel::resized()\r
+{\r
+    updateComponents();\r
+}\r
+\r
+void GraphEditorPanel::changeListenerCallback (ChangeBroadcaster*)\r
+{\r
+    updateComponents();\r
+}\r
+\r
+void GraphEditorPanel::updateComponents()\r
+{\r
+    for (int i = nodes.size(); --i >= 0;)\r
+        if (graph.graph.getNodeForId (nodes.getUnchecked(i)->pluginID) == nullptr)\r
+            nodes.remove (i);\r
+\r
+    for (int i = connectors.size(); --i >= 0;)\r
+        if (! graph.graph.isConnected (connectors.getUnchecked(i)->connection))\r
+            connectors.remove (i);\r
+\r
+    for (auto* fc : nodes)\r
+        fc->update();\r
+\r
+    for (auto* cc : connectors)\r
+        cc->update();\r
+\r
+    for (auto* f : graph.graph.getNodes())\r
+    {\r
+        if (getComponentForFilter (f->nodeID) == 0)\r
+        {\r
+            auto* comp = nodes.add (new FilterComponent (*this, f->nodeID));\r
+            addAndMakeVisible (comp);\r
+            comp->update();\r
+        }\r
+    }\r
+\r
+    for (auto& c : graph.graph.getConnections())\r
+    {\r
+        if (getComponentForConnection (c) == 0)\r
+        {\r
+            auto* comp = connectors.add (new ConnectorComponent (*this));\r
+            addAndMakeVisible (comp);\r
+\r
+            comp->setInput (c.source);\r
+            comp->setOutput (c.destination);\r
+        }\r
+    }\r
+}\r
+\r
+void GraphEditorPanel::showPopupMenu (Point<int> mousePos)\r
+{\r
+    menu = new PopupMenu;\r
+\r
+    if (auto* mainWindow = findParentComponentOfClass<MainHostWindow>())\r
+    {\r
+        mainWindow->addPluginsToMenu (*menu);\r
+\r
+        menu->showMenuAsync ({},\r
+                             ModalCallbackFunction::create ([this, mousePos] (int r)\r
+                                                            {\r
+                                                                if (auto* mainWindow = findParentComponentOfClass<MainHostWindow>())\r
+                                                                    if (auto* desc = mainWindow->getChosenType (r))\r
+                                                                        createNewPlugin (*desc, mousePos);\r
+                                                            }));\r
+    }\r
+}\r
+\r
+void GraphEditorPanel::beginConnectorDrag (AudioProcessorGraph::NodeAndChannel source,\r
+                                           AudioProcessorGraph::NodeAndChannel dest,\r
+                                           const MouseEvent& e)\r
+{\r
+    auto* c = dynamic_cast<ConnectorComponent*> (e.originalComponent);\r
+    connectors.removeObject (c, false);\r
+    draggingConnector = c;\r
+\r
+    if (draggingConnector == nullptr)\r
+        draggingConnector = new ConnectorComponent (*this);\r
+\r
+    draggingConnector->setInput (source);\r
+    draggingConnector->setOutput (dest);\r
+\r
+    addAndMakeVisible (draggingConnector);\r
+    draggingConnector->toFront (false);\r
+\r
+    dragConnector (e);\r
+}\r
+\r
+void GraphEditorPanel::dragConnector (const MouseEvent& e)\r
+{\r
+    auto e2 = e.getEventRelativeTo (this);\r
+\r
+    if (draggingConnector != nullptr)\r
+    {\r
+        draggingConnector->setTooltip ({});\r
+\r
+        auto pos = e2.position;\r
+\r
+        if (auto* pin = findPinAt (pos))\r
+        {\r
+            auto connection = draggingConnector->connection;\r
+\r
+            if (connection.source.nodeID == 0 && ! pin->isInput)\r
+            {\r
+                connection.source = pin->pin;\r
+            }\r
+            else if (connection.destination.nodeID == 0 && pin->isInput)\r
+            {\r
+                connection.destination = pin->pin;\r
+            }\r
+\r
+            if (graph.graph.canConnect (connection))\r
+            {\r
+                pos = (pin->getParentComponent()->getPosition() + pin->getBounds().getCentre()).toFloat();\r
+                draggingConnector->setTooltip (pin->getTooltip());\r
+            }\r
+        }\r
+\r
+        if (draggingConnector->connection.source.nodeID == 0)\r
+            draggingConnector->dragStart (pos);\r
+        else\r
+            draggingConnector->dragEnd (pos);\r
+    }\r
+}\r
+\r
+void GraphEditorPanel::endDraggingConnector (const MouseEvent& e)\r
+{\r
+    if (draggingConnector == nullptr)\r
+        return;\r
+\r
+    draggingConnector->setTooltip ({});\r
+\r
+    auto e2 = e.getEventRelativeTo (this);\r
+    auto connection = draggingConnector->connection;\r
+\r
+    draggingConnector = nullptr;\r
+\r
+    if (auto* pin = findPinAt (e2.position))\r
+    {\r
+        if (connection.source.nodeID == 0)\r
+        {\r
+            if (pin->isInput)\r
+                return;\r
+\r
+            connection.source = pin->pin;\r
+        }\r
+        else\r
+        {\r
+            if (! pin->isInput)\r
+                return;\r
+\r
+            connection.destination = pin->pin;\r
+        }\r
+\r
+        graph.graph.addConnection (connection);\r
+    }\r
+}\r
+\r
+void GraphEditorPanel::timerCallback()\r
+{\r
+    // this should only be called on touch devices\r
+    jassert (isOnTouchDevice());\r
+\r
+    stopTimer();\r
+    showPopupMenu (originalTouchPos);\r
+}\r
+\r
+//==============================================================================\r
+struct GraphDocumentComponent::TooltipBar   : public Component,\r
+                                              private Timer\r
+{\r
+    TooltipBar()\r
+    {\r
+        startTimer (100);\r
+    }\r
+\r
+    void paint (Graphics& g) override\r
+    {\r
+        g.setFont (Font (getHeight() * 0.7f, Font::bold));\r
+        g.setColour (Colours::black);\r
+        g.drawFittedText (tip, 10, 0, getWidth() - 12, getHeight(), Justification::centredLeft, 1);\r
+    }\r
+\r
+    void timerCallback() override\r
+    {\r
+        String newTip;\r
+\r
+        if (auto* underMouse = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse())\r
+            if (auto* ttc = dynamic_cast<TooltipClient*> (underMouse))\r
+                if (! (underMouse->isMouseButtonDown() || underMouse->isCurrentlyBlockedByAnotherModalComponent()))\r
+                    newTip = ttc->getTooltip();\r
+\r
+        if (newTip != tip)\r
+        {\r
+            tip = newTip;\r
+            repaint();\r
+        }\r
+    }\r
+\r
+    String tip;\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TooltipBar)\r
+};\r
+\r
+//==============================================================================\r
+class GraphDocumentComponent::TitleBarComponent    : public Component,\r
+                                                     private Button::Listener\r
+{\r
+public:\r
+    TitleBarComponent (GraphDocumentComponent& graphDocumentComponent)\r
+        : owner (graphDocumentComponent)\r
+    {\r
+        static const unsigned char burgerMenuPathData[]\r
+            = { 110,109,0,0,128,64,0,0,32,65,108,0,0,224,65,0,0,32,65,98,254,212,232,65,0,0,32,65,0,0,240,65,252,\r
+                169,17,65,0,0,240,65,0,0,0,65,98,0,0,240,65,8,172,220,64,254,212,232,65,0,0,192,64,0,0,224,65,0,0,\r
+                192,64,108,0,0,128,64,0,0,192,64,98,16,88,57,64,0,0,192,64,0,0,0,64,8,172,220,64,0,0,0,64,0,0,0,65,\r
+                98,0,0,0,64,252,169,17,65,16,88,57,64,0,0,32,65,0,0,128,64,0,0,32,65,99,109,0,0,224,65,0,0,96,65,108,\r
+                0,0,128,64,0,0,96,65,98,16,88,57,64,0,0,96,65,0,0,0,64,4,86,110,65,0,0,0,64,0,0,128,65,98,0,0,0,64,\r
+                254,212,136,65,16,88,57,64,0,0,144,65,0,0,128,64,0,0,144,65,108,0,0,224,65,0,0,144,65,98,254,212,232,\r
+                65,0,0,144,65,0,0,240,65,254,212,136,65,0,0,240,65,0,0,128,65,98,0,0,240,65,4,86,110,65,254,212,232,\r
+                65,0,0,96,65,0,0,224,65,0,0,96,65,99,109,0,0,224,65,0,0,176,65,108,0,0,128,64,0,0,176,65,98,16,88,57,\r
+                64,0,0,176,65,0,0,0,64,2,43,183,65,0,0,0,64,0,0,192,65,98,0,0,0,64,254,212,200,65,16,88,57,64,0,0,208,\r
+                65,0,0,128,64,0,0,208,65,108,0,0,224,65,0,0,208,65,98,254,212,232,65,0,0,208,65,0,0,240,65,254,212,\r
+                200,65,0,0,240,65,0,0,192,65,98,0,0,240,65,2,43,183,65,254,212,232,65,0,0,176,65,0,0,224,65,0,0,176,\r
+                65,99,101,0,0 };\r
+\r
+        static const unsigned char pluginListPathData[]\r
+            = { 110,109,193,202,222,64,80,50,21,64,108,0,0,48,65,0,0,0,0,108,160,154,112,65,80,50,21,64,108,0,0,48,65,80,\r
+                50,149,64,108,193,202,222,64,80,50,21,64,99,109,0,0,192,64,251,220,127,64,108,160,154,32,65,165,135,202,\r
+                64,108,160,154,32,65,250,220,47,65,108,0,0,192,64,102,144,10,65,108,0,0,192,64,251,220,127,64,99,109,0,0,\r
+                128,65,251,220,127,64,108,0,0,128,65,103,144,10,65,108,96,101,63,65,251,220,47,65,108,96,101,63,65,166,135,\r
+                202,64,108,0,0,128,65,251,220,127,64,99,109,96,101,79,65,148,76,69,65,108,0,0,136,65,0,0,32,65,108,80,\r
+                77,168,65,148,76,69,65,108,0,0,136,65,40,153,106,65,108,96,101,79,65,148,76,69,65,99,109,0,0,64,65,63,247,\r
+                95,65,108,80,77,128,65,233,161,130,65,108,80,77,128,65,125,238,167,65,108,0,0,64,65,51,72,149,65,108,0,0,64,\r
+                65,63,247,95,65,99,109,0,0,176,65,63,247,95,65,108,0,0,176,65,51,72,149,65,108,176,178,143,65,125,238,167,65,\r
+                108,176,178,143,65,233,161,130,65,108,0,0,176,65,63,247,95,65,99,109,12,86,118,63,148,76,69,65,108,0,0,160,\r
+                64,0,0,32,65,108,159,154,16,65,148,76,69,65,108,0,0,160,64,40,153,106,65,108,12,86,118,63,148,76,69,65,99,\r
+                109,0,0,0,0,63,247,95,65,108,62,53,129,64,233,161,130,65,108,62,53,129,64,125,238,167,65,108,0,0,0,0,51,\r
+                72,149,65,108,0,0,0,0,63,247,95,65,99,109,0,0,32,65,63,247,95,65,108,0,0,32,65,51,72,149,65,108,193,202,190,\r
+                64,125,238,167,65,108,193,202,190,64,233,161,130,65,108,0,0,32,65,63,247,95,65,99,101,0,0 };\r
+\r
+        {\r
+            Path p;\r
+            p.loadPathFromData (burgerMenuPathData, sizeof (burgerMenuPathData));\r
+            burgerButton.setShape (p, true, true, false);\r
+        }\r
+\r
+        {\r
+            Path p;\r
+            p.loadPathFromData (pluginListPathData, sizeof (pluginListPathData));\r
+            pluginButton.setShape (p, true, true, false);\r
+        }\r
+\r
+        burgerButton.addListener (this);\r
+        addAndMakeVisible (burgerButton);\r
+\r
+        pluginButton.addListener (this);\r
+        addAndMakeVisible (pluginButton);\r
+\r
+        titleLabel.setJustificationType (Justification::centredLeft);\r
+        addAndMakeVisible (titleLabel);\r
+\r
+        setOpaque (true);\r
+    }\r
+\r
+private:\r
+    void paint (Graphics& g) override\r
+    {\r
+        auto titleBarBackgroundColour = getLookAndFeel().findColour (ResizableWindow::backgroundColourId).darker();\r
+\r
+        g.setColour (titleBarBackgroundColour);\r
+        g.fillRect (getLocalBounds());\r
+    }\r
+\r
+    void resized() override\r
+    {\r
+        auto r = getLocalBounds();\r
+\r
+        burgerButton.setBounds (r.removeFromLeft (40).withSizeKeepingCentre (20, 20));\r
+\r
+        pluginButton.setBounds (r.removeFromRight (40).withSizeKeepingCentre (20, 20));\r
+\r
+        titleLabel.setFont (Font (static_cast<float> (getHeight()) * 0.5f, Font::plain));\r
+        titleLabel.setBounds (r);\r
+    }\r
+\r
+    void buttonClicked (Button* b) override\r
+    {\r
+        owner.showSidePanel (b == &burgerButton);\r
+    }\r
+\r
+    GraphDocumentComponent& owner;\r
+\r
+    Label titleLabel {"titleLabel", "Plugin Host"};\r
+    ShapeButton burgerButton {"burgerButton", Colours::lightgrey, Colours::lightgrey, Colours::white};\r
+    ShapeButton pluginButton {"pluginButton", Colours::lightgrey, Colours::lightgrey, Colours::white};\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TitleBarComponent)\r
+};\r
+\r
+//==============================================================================\r
+struct GraphDocumentComponent::PluginListBoxModel    : public ListBoxModel,\r
+                                                       public ChangeListener,\r
+                                                       public MouseListener\r
+{\r
+    PluginListBoxModel (ListBox& lb, KnownPluginList& kpl)\r
+        : owner (lb),\r
+          knownPlugins (kpl)\r
+    {\r
+        knownPlugins.addChangeListener (this);\r
+        owner.addMouseListener (this, true);\r
+\r
+       #if JUCE_IOS\r
+        scanner = new AUScanner (knownPlugins);\r
+       #endif\r
+    }\r
+\r
+    int getNumRows() override\r
+    {\r
+        return knownPlugins.getNumTypes();\r
+    }\r
+\r
+    void paintListBoxItem (int rowNumber, Graphics& g,\r
+                           int width, int height, bool rowIsSelected) override\r
+    {\r
+        g.fillAll (rowIsSelected ? Colour (0xff42A2C8)\r
+                                 : Colour (0xff263238));\r
+\r
+        g.setColour (rowIsSelected ? Colours::black : Colours::white);\r
+\r
+        if (rowNumber < knownPlugins.getNumTypes())\r
+            g.drawFittedText (knownPlugins.getType (rowNumber)->name,\r
+                              { 0, 0, width, height - 2 },\r
+                              Justification::centred,\r
+                              1);\r
+\r
+        g.setColour (Colours::black.withAlpha (0.4f));\r
+        g.drawRect (0, height - 1, width, 1);\r
+    }\r
+\r
+    var getDragSourceDescription (const SparseSet<int>& selectedRows) override\r
+    {\r
+        if (! isOverSelectedRow)\r
+            return var();\r
+\r
+        return String ("PLUGIN: " + String (selectedRows[0]));\r
+    }\r
+\r
+    void changeListenerCallback (ChangeBroadcaster*) override\r
+    {\r
+        owner.updateContent();\r
+    }\r
+\r
+    void mouseDown (const MouseEvent& e) override\r
+    {\r
+        isOverSelectedRow = owner.getRowPosition (owner.getSelectedRow(), true)\r
+                                 .contains (e.getEventRelativeTo (&owner).getMouseDownPosition());\r
+    }\r
+\r
+    ListBox& owner;\r
+    KnownPluginList& knownPlugins;\r
+\r
+    bool isOverSelectedRow = false;\r
+\r
+   #if JUCE_IOS\r
+    ScopedPointer<AUScanner> scanner;\r
+   #endif\r
+};\r
+\r
+//==============================================================================\r
+GraphDocumentComponent::GraphDocumentComponent (AudioPluginFormatManager& fm,\r
+                                                AudioDeviceManager& dm,\r
+                                                KnownPluginList& kpl)\r
+    : graph (new FilterGraph (fm)),\r
+      deviceManager (dm),\r
+      pluginList (kpl),\r
+      graphPlayer (getAppProperties().getUserSettings()->getBoolValue ("doublePrecisionProcessing", false))\r
+{\r
+    init();\r
+\r
+    deviceManager.addChangeListener (graphPanel);\r
+    deviceManager.addAudioCallback (&graphPlayer);\r
+    deviceManager.addMidiInputCallback (String(), &graphPlayer.getMidiMessageCollector());\r
+}\r
+\r
+void GraphDocumentComponent::init()\r
+{\r
+    addAndMakeVisible (graphPanel = new GraphEditorPanel (*graph));\r
+    graphPlayer.setProcessor (&graph->graph);\r
+\r
+    keyState.addListener (&graphPlayer.getMidiMessageCollector());\r
+\r
+    addAndMakeVisible (keyboardComp = new MidiKeyboardComponent (keyState, MidiKeyboardComponent::horizontalKeyboard));\r
+    addAndMakeVisible (statusBar = new TooltipBar());\r
+\r
+    graphPanel->updateComponents();\r
+\r
+    if (isOnTouchDevice())\r
+    {\r
+        if (isOnTouchDevice())\r
+            addAndMakeVisible (titleBarComponent = new TitleBarComponent (*this));\r
+\r
+        pluginListBoxModel = new PluginListBoxModel (pluginListBox, pluginList);\r
+\r
+        pluginListBox.setModel (pluginListBoxModel);\r
+        pluginListBox.setRowHeight (40);\r
+\r
+        pluginListSidePanel.setContent (&pluginListBox, false);\r
+\r
+        mobileSettingsSidePanel.setContent (new AudioDeviceSelectorComponent (deviceManager,\r
+                                                                              0, 2, 0, 2,\r
+                                                                              true, true, true, false));\r
+\r
+        if (isOnTouchDevice())\r
+        {\r
+            addAndMakeVisible (pluginListSidePanel);\r
+            addAndMakeVisible (mobileSettingsSidePanel);\r
+        }\r
+    }\r
+}\r
+\r
+GraphDocumentComponent::~GraphDocumentComponent()\r
+{\r
+    releaseGraph();\r
+\r
+    keyState.removeListener (&graphPlayer.getMidiMessageCollector());\r
+}\r
+\r
+void GraphDocumentComponent::resized()\r
+{\r
+    auto r = getLocalBounds();\r
+    const int titleBarHeight = 40;\r
+    const int keysHeight = 60;\r
+    const int statusHeight = 20;\r
+\r
+    if (isOnTouchDevice())\r
+        titleBarComponent->setBounds (r.removeFromTop(titleBarHeight));\r
+\r
+    keyboardComp->setBounds (r.removeFromBottom (keysHeight));\r
+    statusBar->setBounds (r.removeFromBottom (statusHeight));\r
+    graphPanel->setBounds (r);\r
+\r
+    checkAvailableWidth();\r
+}\r
+\r
+void GraphDocumentComponent::createNewPlugin (const PluginDescription& desc, Point<int> pos)\r
+{\r
+    graphPanel->createNewPlugin (desc, pos);\r
+}\r
+\r
+void GraphDocumentComponent::unfocusKeyboardComponent()\r
+{\r
+    keyboardComp->unfocusAllComponents();\r
+}\r
+\r
+void GraphDocumentComponent::releaseGraph()\r
+{\r
+    deviceManager.removeAudioCallback (&graphPlayer);\r
+    deviceManager.removeMidiInputCallback (String(), &graphPlayer.getMidiMessageCollector());\r
+\r
+    if (graphPanel != nullptr)\r
+    {\r
+        deviceManager.removeChangeListener (graphPanel);\r
+        graphPanel = nullptr;\r
+    }\r
+\r
+    keyboardComp = nullptr;\r
+    statusBar = nullptr;\r
+\r
+    graphPlayer.setProcessor (nullptr);\r
+    graph = nullptr;\r
+}\r
+\r
+bool GraphDocumentComponent::isInterestedInDragSource (const SourceDetails& details)\r
+{\r
+    return ((dynamic_cast<ListBox*> (details.sourceComponent.get()) != nullptr)\r
+            && details.description.toString().startsWith ("PLUGIN"));\r
+}\r
+\r
+void GraphDocumentComponent::itemDropped (const SourceDetails& details)\r
+{\r
+    // don't allow items to be dropped behind the sidebar\r
+    if (pluginListSidePanel.getBounds().contains (details.localPosition))\r
+        return;\r
+\r
+    auto pluginTypeIndex = details.description.toString()\r
+                                 .fromFirstOccurrenceOf ("PLUGIN: ", false, false)\r
+                                 .getIntValue();\r
+\r
+    // must be a valid index!\r
+    jassert (isPositiveAndBelow (pluginTypeIndex, pluginList.getNumTypes()));\r
+\r
+    createNewPlugin (*pluginList.getType (pluginTypeIndex), details.localPosition);\r
+}\r
+\r
+void GraphDocumentComponent::showSidePanel (bool showSettingsPanel)\r
+{\r
+    if (showSettingsPanel)\r
+        mobileSettingsSidePanel.showOrHide (true);\r
+    else\r
+        pluginListSidePanel.showOrHide (true);\r
+\r
+    checkAvailableWidth();\r
+\r
+    lastOpenedSidePanel = showSettingsPanel ? &mobileSettingsSidePanel\r
+                                            : &pluginListSidePanel;\r
+}\r
+\r
+void GraphDocumentComponent::hideLastSidePanel()\r
+{\r
+    if (lastOpenedSidePanel != nullptr)\r
+        lastOpenedSidePanel->showOrHide (false);\r
+\r
+    if      (mobileSettingsSidePanel.isPanelShowing())    lastOpenedSidePanel = &mobileSettingsSidePanel;\r
+    else if (pluginListSidePanel.isPanelShowing())        lastOpenedSidePanel = &pluginListSidePanel;\r
+    else                                                  lastOpenedSidePanel = nullptr;\r
+}\r
+\r
+void GraphDocumentComponent::checkAvailableWidth()\r
+{\r
+    if (mobileSettingsSidePanel.isPanelShowing() && pluginListSidePanel.isPanelShowing())\r
+    {\r
+        if (getWidth() - (mobileSettingsSidePanel.getWidth() + pluginListSidePanel.getWidth()) < 150)\r
+            hideLastSidePanel();\r
+    }\r
+}\r
+\r
+void GraphDocumentComponent::setDoublePrecision (bool doublePrecision)\r
+{\r
+    graphPlayer.setDoublePrecisionProcessing (doublePrecision);\r
+}\r
+\r
+bool GraphDocumentComponent::closeAnyOpenPluginWindows()\r
+{\r
+    return graphPanel->graph.closeAnyOpenPluginWindows();\r
+}\r
diff --git a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.h b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.h
new file mode 100644 (file)
index 0000000..cf24387
--- /dev/null
@@ -0,0 +1,168 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#pragma once\r
+\r
+#include "../Filters/FilterGraph.h"\r
+\r
+class MainHostWindow;\r
+\r
+//==============================================================================\r
+/**\r
+    A panel that displays and edits a FilterGraph.\r
+*/\r
+class GraphEditorPanel   : public Component,\r
+                           public ChangeListener,\r
+                           private Timer\r
+{\r
+public:\r
+    GraphEditorPanel (FilterGraph& graph);\r
+    ~GraphEditorPanel();\r
+\r
+    void createNewPlugin (const PluginDescription&, Point<int> position);\r
+\r
+    void paint (Graphics&) override;\r
+    void resized() override;\r
+\r
+    void mouseDown (const MouseEvent&) override;\r
+    void mouseUp   (const MouseEvent&) override;\r
+    void mouseDrag (const MouseEvent&) override;\r
+\r
+    void changeListenerCallback (ChangeBroadcaster*) override;\r
+\r
+    //==============================================================================\r
+    void updateComponents();\r
+\r
+    //==============================================================================\r
+    void showPopupMenu (Point<int> position);\r
+\r
+    //==============================================================================\r
+    void beginConnectorDrag (AudioProcessorGraph::NodeAndChannel source,\r
+                             AudioProcessorGraph::NodeAndChannel dest,\r
+                             const MouseEvent&);\r
+    void dragConnector (const MouseEvent&);\r
+    void endDraggingConnector (const MouseEvent&);\r
+\r
+    //==============================================================================\r
+    FilterGraph& graph;\r
+\r
+private:\r
+    struct FilterComponent;\r
+    struct ConnectorComponent;\r
+    struct PinComponent;\r
+\r
+    OwnedArray<FilterComponent> nodes;\r
+    OwnedArray<ConnectorComponent> connectors;\r
+    ScopedPointer<ConnectorComponent> draggingConnector;\r
+    ScopedPointer<PopupMenu> menu;\r
+\r
+    FilterComponent* getComponentForFilter (AudioProcessorGraph::NodeID) const;\r
+    ConnectorComponent* getComponentForConnection (const AudioProcessorGraph::Connection&) const;\r
+    PinComponent* findPinAt (Point<float>) const;\r
+\r
+    //==============================================================================\r
+    Point<int> originalTouchPos;\r
+\r
+    void timerCallback() override;\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GraphEditorPanel)\r
+};\r
+\r
+\r
+//==============================================================================\r
+/**\r
+    A panel that embeds a GraphEditorPanel with a midi keyboard at the bottom.\r
+\r
+    It also manages the graph itself, and plays it.\r
+*/\r
+class GraphDocumentComponent  : public Component,\r
+                                public DragAndDropTarget,\r
+                                public DragAndDropContainer\r
+{\r
+public:\r
+    GraphDocumentComponent (AudioPluginFormatManager& formatManager,\r
+                            AudioDeviceManager& deviceManager,\r
+                            KnownPluginList& pluginList);\r
+\r
+    ~GraphDocumentComponent();\r
+\r
+    //==============================================================================\r
+    void createNewPlugin (const PluginDescription&, Point<int> position);\r
+    void setDoublePrecision (bool doublePrecision);\r
+    bool closeAnyOpenPluginWindows();\r
+\r
+    //==============================================================================\r
+    ScopedPointer<FilterGraph> graph;\r
+\r
+    void resized() override;\r
+    void unfocusKeyboardComponent();\r
+    void releaseGraph();\r
+\r
+    //==============================================================================\r
+    bool isInterestedInDragSource (const SourceDetails&) override;\r
+    void itemDropped (const SourceDetails&) override;\r
+\r
+    //==============================================================================\r
+    ScopedPointer<GraphEditorPanel> graphPanel;\r
+    ScopedPointer<MidiKeyboardComponent> keyboardComp;\r
+\r
+    //==============================================================================\r
+    void showSidePanel (bool isSettingsPanel);\r
+    void hideLastSidePanel();\r
+\r
+    BurgerMenuComponent burgerMenu;\r
+\r
+private:\r
+    //==============================================================================\r
+    AudioDeviceManager& deviceManager;\r
+    KnownPluginList& pluginList;\r
+\r
+    AudioProcessorPlayer graphPlayer;\r
+    MidiKeyboardState keyState;\r
+\r
+    struct TooltipBar;\r
+    ScopedPointer<TooltipBar> statusBar;\r
+\r
+    class TitleBarComponent;\r
+    ScopedPointer<TitleBarComponent> titleBarComponent;\r
+\r
+    //==============================================================================\r
+    struct PluginListBoxModel;\r
+    ScopedPointer<PluginListBoxModel> pluginListBoxModel;\r
+\r
+    ListBox pluginListBox;\r
+\r
+    SidePanel mobileSettingsSidePanel { "Settings", 300, true };\r
+    SidePanel pluginListSidePanel    { "Plugins", 250, false };\r
+    SidePanel* lastOpenedSidePanel = nullptr;\r
+\r
+    //==============================================================================\r
+    void init();\r
+    void checkAvailableWidth();\r
+\r
+    //==============================================================================\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GraphDocumentComponent)\r
+};\r
diff --git a/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp b/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp
new file mode 100644 (file)
index 0000000..23f99fc
--- /dev/null
@@ -0,0 +1,646 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#include "../JuceLibraryCode/JuceHeader.h"\r
+#include "MainHostWindow.h"\r
+#include "../Filters/InternalFilters.h"\r
+\r
+\r
+//==============================================================================\r
+class MainHostWindow::PluginListWindow  : public DocumentWindow\r
+{\r
+public:\r
+    PluginListWindow (MainHostWindow& mw, AudioPluginFormatManager& pluginFormatManager)\r
+        : DocumentWindow ("Available Plugins",\r
+                          LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),\r
+                          DocumentWindow::minimiseButton | DocumentWindow::closeButton),\r
+          owner (mw)\r
+    {\r
+        auto deadMansPedalFile = getAppProperties().getUserSettings()\r
+                                   ->getFile().getSiblingFile ("RecentlyCrashedPluginsList");\r
+\r
+        setContentOwned (new PluginListComponent (pluginFormatManager,\r
+                                                  owner.knownPluginList,\r
+                                                  deadMansPedalFile,\r
+                                                  getAppProperties().getUserSettings(), true), true);\r
+\r
+        setResizable (true, false);\r
+        setResizeLimits (300, 400, 800, 1500);\r
+        setTopLeftPosition (60, 60);\r
+\r
+        restoreWindowStateFromString (getAppProperties().getUserSettings()->getValue ("listWindowPos"));\r
+        setVisible (true);\r
+    }\r
+\r
+    ~PluginListWindow()\r
+    {\r
+        getAppProperties().getUserSettings()->setValue ("listWindowPos", getWindowStateAsString());\r
+        clearContentComponent();\r
+    }\r
+\r
+    void closeButtonPressed() override\r
+    {\r
+        owner.pluginListWindow = nullptr;\r
+    }\r
+\r
+private:\r
+    MainHostWindow& owner;\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListWindow)\r
+};\r
+\r
+//==============================================================================\r
+MainHostWindow::MainHostWindow()\r
+    : DocumentWindow (JUCEApplication::getInstance()->getApplicationName(),\r
+                      LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),\r
+                      DocumentWindow::allButtons)\r
+{\r
+    formatManager.addDefaultFormats();\r
+    formatManager.addFormat (new InternalPluginFormat());\r
+\r
+    RuntimePermissions::request (RuntimePermissions::recordAudio,\r
+                                 [safeThis = SafePointer<MainHostWindow> (this)] (bool granted) mutable\r
+                                 {\r
+                                     ScopedPointer<XmlElement> savedAudioState (getAppProperties().getUserSettings()\r
+                                                                                ->getXmlValue ("audioDeviceState"));\r
+\r
+                                     safeThis->deviceManager.initialise (granted ? 256 : 0, 256, savedAudioState, true);\r
+                                 });\r
+\r
+   #if JUCE_IOS || JUCE_ANDROID\r
+    setFullScreen (true);\r
+   #else\r
+    setResizable (true, false);\r
+    setResizeLimits (500, 400, 10000, 10000);\r
+    centreWithSize (800, 600);\r
+   #endif\r
+\r
+    graphHolder = new GraphDocumentComponent (formatManager, deviceManager, knownPluginList);\r
+\r
+    setContentNonOwned (graphHolder, false);\r
+\r
+    restoreWindowStateFromString (getAppProperties().getUserSettings()->getValue ("mainWindowPos"));\r
+\r
+    setVisible (true);\r
+\r
+    InternalPluginFormat internalFormat;\r
+    internalFormat.getAllTypes (internalTypes);\r
+\r
+    ScopedPointer<XmlElement> savedPluginList (getAppProperties().getUserSettings()->getXmlValue ("pluginList"));\r
+\r
+    if (savedPluginList != nullptr)\r
+        knownPluginList.recreateFromXml (*savedPluginList);\r
+\r
+    for (auto* t : internalTypes)\r
+        knownPluginList.addType (*t);\r
+\r
+    pluginSortMethod = (KnownPluginList::SortMethod) getAppProperties().getUserSettings()\r
+                            ->getIntValue ("pluginSortMethod", KnownPluginList::sortByManufacturer);\r
+\r
+    knownPluginList.addChangeListener (this);\r
+\r
+    if (auto* filterGraph = graphHolder->graph.get())\r
+        filterGraph->addChangeListener (this);\r
+\r
+    addKeyListener (getCommandManager().getKeyMappings());\r
+\r
+    Process::setPriority (Process::HighPriority);\r
+\r
+  #if JUCE_IOS || JUCE_ANDROID\r
+    graphHolder->burgerMenu.setModel (this);\r
+  #else\r
+   #if JUCE_MAC\r
+    setMacMainMenu (this);\r
+   #else\r
+    setMenuBar (this);\r
+   #endif\r
+  #endif\r
+\r
+    getCommandManager().setFirstCommandTarget (this);\r
+}\r
+\r
+MainHostWindow::~MainHostWindow()\r
+{\r
+    pluginListWindow = nullptr;\r
+    knownPluginList.removeChangeListener (this);\r
+\r
+    if (auto* filterGraph = graphHolder->graph.get())\r
+        filterGraph->removeChangeListener (this);\r
+\r
+    getAppProperties().getUserSettings()->setValue ("mainWindowPos", getWindowStateAsString());\r
+    clearContentComponent();\r
+\r
+  #if ! (JUCE_ANDROID || JUCE_IOS)\r
+   #if JUCE_MAC\r
+    setMacMainMenu (nullptr);\r
+   #else\r
+    setMenuBar (nullptr);\r
+   #endif\r
+  #endif\r
+\r
+    graphHolder = nullptr;\r
+}\r
+\r
+void MainHostWindow::closeButtonPressed()\r
+{\r
+    tryToQuitApplication();\r
+}\r
+\r
+struct AsyncQuitRetrier  : private Timer\r
+{\r
+    AsyncQuitRetrier()   { startTimer (500); }\r
+\r
+    void timerCallback() override\r
+    {\r
+        stopTimer();\r
+        delete this;\r
+\r
+        if (auto app = JUCEApplicationBase::getInstance())\r
+            app->systemRequestedQuit();\r
+    }\r
+};\r
+\r
+void MainHostWindow::tryToQuitApplication()\r
+{\r
+    if (graphHolder->closeAnyOpenPluginWindows())\r
+    {\r
+        // Really important thing to note here: if the last call just deleted any plugin windows,\r
+        // we won't exit immediately - instead we'll use our AsyncQuitRetrier to let the message\r
+        // loop run for another brief moment, then try again. This will give any plugins a chance\r
+        // to flush any GUI events that may have been in transit before the app forces them to\r
+        // be unloaded\r
+        new AsyncQuitRetrier();\r
+    }\r
+    else if (ModalComponentManager::getInstance()->cancelAllModalComponents())\r
+    {\r
+        new AsyncQuitRetrier();\r
+    }\r
+   #if JUCE_ANDROID || JUCE_IOS\r
+    else if (graphHolder == nullptr || graphHolder->graph->saveDocument (FilterGraph::getDefaultGraphDocumentOnMobile()))\r
+   #else\r
+    else if (graphHolder == nullptr || graphHolder->graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)\r
+   #endif\r
+    {\r
+        // Some plug-ins do not want [NSApp stop] to be called\r
+        // before the plug-ins are not deallocated.\r
+        graphHolder->releaseGraph();\r
+\r
+        JUCEApplication::quit();\r
+    }\r
+}\r
+\r
+void MainHostWindow::changeListenerCallback (ChangeBroadcaster* changed)\r
+{\r
+    if (changed == &knownPluginList)\r
+    {\r
+        menuItemsChanged();\r
+\r
+        // save the plugin list every time it gets changed, so that if we're scanning\r
+        // and it crashes, we've still saved the previous ones\r
+        ScopedPointer<XmlElement> savedPluginList (knownPluginList.createXml());\r
+\r
+        if (savedPluginList != nullptr)\r
+        {\r
+            getAppProperties().getUserSettings()->setValue ("pluginList", savedPluginList);\r
+            getAppProperties().saveIfNeeded();\r
+        }\r
+    }\r
+    else if (graphHolder != nullptr && changed == graphHolder->graph)\r
+    {\r
+        auto title = JUCEApplication::getInstance()->getApplicationName();\r
+        auto f = graphHolder->graph->getFile();\r
+\r
+        if (f.existsAsFile())\r
+            title = f.getFileName() + " - " + title;\r
+\r
+        setName (title);\r
+    }\r
+}\r
+\r
+StringArray MainHostWindow::getMenuBarNames()\r
+{\r
+    StringArray names;\r
+    names.add ("File");\r
+    names.add ("Plugins");\r
+    names.add ("Options");\r
+    names.add ("Windows");\r
+    return names;\r
+}\r
+\r
+PopupMenu MainHostWindow::getMenuForIndex (int topLevelMenuIndex, const String& /*menuName*/)\r
+{\r
+    PopupMenu menu;\r
+\r
+    if (topLevelMenuIndex == 0)\r
+    {\r
+        // "File" menu\r
+       #if ! (JUCE_IOS || JUCE_ANDROID)\r
+        menu.addCommandItem (&getCommandManager(), CommandIDs::newFile);\r
+        menu.addCommandItem (&getCommandManager(), CommandIDs::open);\r
+       #endif\r
+\r
+        RecentlyOpenedFilesList recentFiles;\r
+        recentFiles.restoreFromString (getAppProperties().getUserSettings()\r
+                                            ->getValue ("recentFilterGraphFiles"));\r
+\r
+        PopupMenu recentFilesMenu;\r
+        recentFiles.createPopupMenuItems (recentFilesMenu, 100, true, true);\r
+        menu.addSubMenu ("Open recent file", recentFilesMenu);\r
+\r
+       #if ! (JUCE_IOS || JUCE_ANDROID)\r
+        menu.addCommandItem (&getCommandManager(), CommandIDs::save);\r
+        menu.addCommandItem (&getCommandManager(), CommandIDs::saveAs);\r
+       #endif\r
+\r
+        menu.addSeparator();\r
+        menu.addCommandItem (&getCommandManager(), StandardApplicationCommandIDs::quit);\r
+    }\r
+    else if (topLevelMenuIndex == 1)\r
+    {\r
+        // "Plugins" menu\r
+        PopupMenu pluginsMenu;\r
+        addPluginsToMenu (pluginsMenu);\r
+        menu.addSubMenu ("Create plugin", pluginsMenu);\r
+        menu.addSeparator();\r
+        menu.addItem (250, "Delete all plugins");\r
+    }\r
+    else if (topLevelMenuIndex == 2)\r
+    {\r
+        // "Options" menu\r
+\r
+        menu.addCommandItem (&getCommandManager(), CommandIDs::showPluginListEditor);\r
+\r
+        PopupMenu sortTypeMenu;\r
+        sortTypeMenu.addItem (200, "List plugins in default order",      true, pluginSortMethod == KnownPluginList::defaultOrder);\r
+        sortTypeMenu.addItem (201, "List plugins in alphabetical order", true, pluginSortMethod == KnownPluginList::sortAlphabetically);\r
+        sortTypeMenu.addItem (202, "List plugins by category",           true, pluginSortMethod == KnownPluginList::sortByCategory);\r
+        sortTypeMenu.addItem (203, "List plugins by manufacturer",       true, pluginSortMethod == KnownPluginList::sortByManufacturer);\r
+        sortTypeMenu.addItem (204, "List plugins based on the directory structure", true, pluginSortMethod == KnownPluginList::sortByFileSystemLocation);\r
+        menu.addSubMenu ("Plugin menu type", sortTypeMenu);\r
+\r
+        menu.addSeparator();\r
+        menu.addCommandItem (&getCommandManager(), CommandIDs::showAudioSettings);\r
+        menu.addCommandItem (&getCommandManager(), CommandIDs::toggleDoublePrecision);\r
+\r
+        menu.addSeparator();\r
+        menu.addCommandItem (&getCommandManager(), CommandIDs::aboutBox);\r
+    }\r
+    else if (topLevelMenuIndex == 3)\r
+    {\r
+        menu.addCommandItem (&getCommandManager(), CommandIDs::allWindowsForward);\r
+    }\r
+\r
+    return menu;\r
+}\r
+\r
+void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/)\r
+{\r
+    if (menuItemID == 250)\r
+    {\r
+        if (graphHolder != nullptr)\r
+            if (auto* graph = graphHolder->graph.get())\r
+                graph->clear();\r
+    }\r
+   #if ! (JUCE_ANDROID || JUCE_IOS)\r
+    else if (menuItemID >= 100 && menuItemID < 200)\r
+    {\r
+        RecentlyOpenedFilesList recentFiles;\r
+        recentFiles.restoreFromString (getAppProperties().getUserSettings()\r
+                                            ->getValue ("recentFilterGraphFiles"));\r
+\r
+        if (graphHolder != nullptr)\r
+            if (auto* graph = graphHolder->graph.get())\r
+                if (graph != nullptr && graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)\r
+                    graph->loadFrom (recentFiles.getFile (menuItemID - 100), true);\r
+    }\r
+   #endif\r
+    else if (menuItemID >= 200 && menuItemID < 210)\r
+    {\r
+             if (menuItemID == 200)     pluginSortMethod = KnownPluginList::defaultOrder;\r
+        else if (menuItemID == 201)     pluginSortMethod = KnownPluginList::sortAlphabetically;\r
+        else if (menuItemID == 202)     pluginSortMethod = KnownPluginList::sortByCategory;\r
+        else if (menuItemID == 203)     pluginSortMethod = KnownPluginList::sortByManufacturer;\r
+        else if (menuItemID == 204)     pluginSortMethod = KnownPluginList::sortByFileSystemLocation;\r
+\r
+        getAppProperties().getUserSettings()->setValue ("pluginSortMethod", (int) pluginSortMethod);\r
+\r
+        menuItemsChanged();\r
+    }\r
+    else\r
+    {\r
+        if (auto* desc = getChosenType (menuItemID))\r
+            createPlugin (*desc,\r
+                          { proportionOfWidth  (0.3f + Random::getSystemRandom().nextFloat() * 0.6f),\r
+                            proportionOfHeight (0.3f + Random::getSystemRandom().nextFloat() * 0.6f) });\r
+    }\r
+}\r
+\r
+void MainHostWindow::menuBarActivated (bool isActivated)\r
+{\r
+    if (isActivated && graphHolder != nullptr)\r
+        graphHolder->unfocusKeyboardComponent();\r
+}\r
+\r
+void MainHostWindow::createPlugin (const PluginDescription& desc, Point<int> pos)\r
+{\r
+    if (graphHolder != nullptr)\r
+        graphHolder->createNewPlugin (desc, pos);\r
+}\r
+\r
+void MainHostWindow::addPluginsToMenu (PopupMenu& m) const\r
+{\r
+    if (graphHolder != nullptr)\r
+    {\r
+        int i = 0;\r
+\r
+        for (auto* t : internalTypes)\r
+            m.addItem (++i, t->name + " (" + t->pluginFormatName + ")",\r
+                       graphHolder->graph->getNodeForName (t->name) == nullptr);\r
+    }\r
+\r
+    m.addSeparator();\r
+\r
+    knownPluginList.addToMenu (m, pluginSortMethod);\r
+}\r
+\r
+const PluginDescription* MainHostWindow::getChosenType (const int menuID) const\r
+{\r
+    if (menuID >= 1 && menuID < 1 + internalTypes.size())\r
+        return internalTypes [menuID - 1];\r
+\r
+    return knownPluginList.getType (knownPluginList.getIndexChosenByMenu (menuID));\r
+}\r
+\r
+//==============================================================================\r
+ApplicationCommandTarget* MainHostWindow::getNextCommandTarget()\r
+{\r
+    return findFirstTargetParentComponent();\r
+}\r
+\r
+void MainHostWindow::getAllCommands (Array<CommandID>& commands)\r
+{\r
+    // this returns the set of all commands that this target can perform..\r
+    const CommandID ids[] = {\r
+                             #if ! (JUCE_IOS || JUCE_ANDROID)\r
+                              CommandIDs::newFile,\r
+                              CommandIDs::open,\r
+                              CommandIDs::save,\r
+                              CommandIDs::saveAs,\r
+                             #endif\r
+                              CommandIDs::showPluginListEditor,\r
+                              CommandIDs::showAudioSettings,\r
+                              CommandIDs::toggleDoublePrecision,\r
+                              CommandIDs::aboutBox,\r
+                              CommandIDs::allWindowsForward\r
+                            };\r
+\r
+    commands.addArray (ids, numElementsInArray (ids));\r
+}\r
+\r
+void MainHostWindow::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result)\r
+{\r
+    const String category ("General");\r
+\r
+    switch (commandID)\r
+    {\r
+   #if ! (JUCE_IOS || JUCE_ANDROID)\r
+    case CommandIDs::newFile:\r
+        result.setInfo ("New", "Creates a new filter graph file", category, 0);\r
+        result.defaultKeypresses.add(KeyPress('n', ModifierKeys::commandModifier, 0));\r
+        break;\r
+\r
+    case CommandIDs::open:\r
+        result.setInfo ("Open...", "Opens a filter graph file", category, 0);\r
+        result.defaultKeypresses.add (KeyPress ('o', ModifierKeys::commandModifier, 0));\r
+        break;\r
+\r
+    case CommandIDs::save:\r
+        result.setInfo ("Save", "Saves the current graph to a file", category, 0);\r
+        result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier, 0));\r
+        break;\r
+\r
+    case CommandIDs::saveAs:\r
+        result.setInfo ("Save As...",\r
+                        "Saves a copy of the current graph to a file",\r
+                        category, 0);\r
+        result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::shiftModifier | ModifierKeys::commandModifier, 0));\r
+        break;\r
+   #endif\r
+\r
+    case CommandIDs::showPluginListEditor:\r
+        result.setInfo ("Edit the list of available plug-Ins...", String(), category, 0);\r
+        result.addDefaultKeypress ('p', ModifierKeys::commandModifier);\r
+        break;\r
+\r
+    case CommandIDs::showAudioSettings:\r
+        result.setInfo ("Change the audio device settings", String(), category, 0);\r
+        result.addDefaultKeypress ('a', ModifierKeys::commandModifier);\r
+        break;\r
+\r
+    case CommandIDs::toggleDoublePrecision:\r
+        updatePrecisionMenuItem (result);\r
+        break;\r
+\r
+    case CommandIDs::aboutBox:\r
+        result.setInfo ("About...", String(), category, 0);\r
+        break;\r
+\r
+    case CommandIDs::allWindowsForward:\r
+        result.setInfo ("All Windows Forward", "Bring all plug-in windows forward", category, 0);\r
+        result.addDefaultKeypress ('w', ModifierKeys::commandModifier);\r
+        break;\r
+\r
+    default:\r
+        break;\r
+    }\r
+}\r
+\r
+bool MainHostWindow::perform (const InvocationInfo& info)\r
+{\r
+    switch (info.commandID)\r
+    {\r
+   #if ! (JUCE_IOS || JUCE_ANDROID)\r
+    case CommandIDs::newFile:\r
+        if (graphHolder != nullptr && graphHolder->graph != nullptr && graphHolder->graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)\r
+            graphHolder->graph->newDocument();\r
+        break;\r
+\r
+    case CommandIDs::open:\r
+        if (graphHolder != nullptr && graphHolder->graph != nullptr && graphHolder->graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)\r
+            graphHolder->graph->loadFromUserSpecifiedFile (true);\r
+        break;\r
+\r
+    case CommandIDs::save:\r
+        if (graphHolder != nullptr && graphHolder->graph != nullptr)\r
+            graphHolder->graph->save (true, true);\r
+        break;\r
+\r
+    case CommandIDs::saveAs:\r
+        if (graphHolder != nullptr && graphHolder->graph != nullptr)\r
+            graphHolder->graph->saveAs (File(), true, true, true);\r
+        break;\r
+   #endif\r
+\r
+    case CommandIDs::showPluginListEditor:\r
+        if (pluginListWindow == nullptr)\r
+            pluginListWindow = new PluginListWindow (*this, formatManager);\r
+\r
+        pluginListWindow->toFront (true);\r
+        break;\r
+\r
+    case CommandIDs::showAudioSettings:\r
+        showAudioSettings();\r
+        break;\r
+\r
+    case CommandIDs::toggleDoublePrecision:\r
+        if (auto* props = getAppProperties().getUserSettings())\r
+        {\r
+            bool newIsDoublePrecision = ! isDoublePrecisionProcessing();\r
+            props->setValue ("doublePrecisionProcessing", var (newIsDoublePrecision));\r
+\r
+            {\r
+                ApplicationCommandInfo cmdInfo (info.commandID);\r
+                updatePrecisionMenuItem (cmdInfo);\r
+                menuItemsChanged();\r
+            }\r
+\r
+            if (graphHolder != nullptr)\r
+                graphHolder->setDoublePrecision (newIsDoublePrecision);\r
+        }\r
+        break;\r
+\r
+    case CommandIDs::aboutBox:\r
+        // TODO\r
+        break;\r
+\r
+    case CommandIDs::allWindowsForward:\r
+    {\r
+        auto& desktop = Desktop::getInstance();\r
+\r
+        for (int i = 0; i < desktop.getNumComponents(); ++i)\r
+            desktop.getComponent (i)->toBehind (this);\r
+\r
+        break;\r
+    }\r
+\r
+    default:\r
+        return false;\r
+    }\r
+\r
+    return true;\r
+}\r
+\r
+void MainHostWindow::showAudioSettings()\r
+{\r
+    auto* audioSettingsComp = new AudioDeviceSelectorComponent (deviceManager,\r
+                                                                0, 256,\r
+                                                                0, 256,\r
+                                                                true, true,\r
+                                                                true, false);\r
+\r
+    audioSettingsComp->setSize (500, 450);\r
+\r
+    DialogWindow::LaunchOptions o;\r
+    o.content.setOwned (audioSettingsComp);\r
+    o.dialogTitle                   = "Audio Settings";\r
+    o.componentToCentreAround       = this;\r
+    o.dialogBackgroundColour        = getLookAndFeel().findColour (ResizableWindow::backgroundColourId);\r
+    o.escapeKeyTriggersCloseButton  = true;\r
+    o.useNativeTitleBar             = false;\r
+    o.resizable                     = false;\r
+\r
+     auto* w = o.create();\r
+     w->enterModalState (true,\r
+                         ModalCallbackFunction::create\r
+                         ([safeThis = SafePointer<MainHostWindow> (this)] (int)\r
+                         {\r
+                             ScopedPointer<XmlElement> audioState (safeThis->deviceManager.createStateXml());\r
+\r
+                             getAppProperties().getUserSettings()->setValue ("audioDeviceState", audioState);\r
+                             getAppProperties().getUserSettings()->saveIfNeeded();\r
+\r
+                             if (safeThis->graphHolder != nullptr)\r
+                                 if (safeThis->graphHolder->graph != nullptr)\r
+                                     safeThis->graphHolder->graph->graph.removeIllegalConnections();\r
+                         }), true);\r
+}\r
+\r
+bool MainHostWindow::isInterestedInFileDrag (const StringArray&)\r
+{\r
+    return true;\r
+}\r
+\r
+void MainHostWindow::fileDragEnter (const StringArray&, int, int)\r
+{\r
+}\r
+\r
+void MainHostWindow::fileDragMove (const StringArray&, int, int)\r
+{\r
+}\r
+\r
+void MainHostWindow::fileDragExit (const StringArray&)\r
+{\r
+}\r
+\r
+void MainHostWindow::filesDropped (const StringArray& files, int x, int y)\r
+{\r
+    if (graphHolder != nullptr)\r
+    {\r
+       #if ! (JUCE_ANDROID || JUCE_IOS)\r
+        if (files.size() == 1 && File (files[0]).hasFileExtension (FilterGraph::getFilenameSuffix()))\r
+        {\r
+            if (auto* filterGraph = graphHolder->graph.get())\r
+                if (filterGraph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)\r
+                    filterGraph->loadFrom (File (files[0]), true);\r
+        }\r
+        else\r
+       #endif\r
+        {\r
+            OwnedArray<PluginDescription> typesFound;\r
+            knownPluginList.scanAndAddDragAndDroppedFiles (formatManager, files, typesFound);\r
+\r
+            auto pos = graphHolder->getLocalPoint (this, Point<int> (x, y));\r
+\r
+            for (int i = 0; i < jmin (5, typesFound.size()); ++i)\r
+                if (auto* desc = typesFound.getUnchecked(i))\r
+                    createPlugin (*desc, pos);\r
+        }\r
+    }\r
+}\r
+\r
+bool MainHostWindow::isDoublePrecisionProcessing()\r
+{\r
+    if (auto* props = getAppProperties().getUserSettings())\r
+        return props->getBoolValue ("doublePrecisionProcessing", false);\r
+\r
+    return false;\r
+}\r
+\r
+void MainHostWindow::updatePrecisionMenuItem (ApplicationCommandInfo& info)\r
+{\r
+    info.setInfo ("Double floating point precision rendering", String(), "General", 0);\r
+    info.setTicked (isDoublePrecisionProcessing());\r
+}\r
diff --git a/extras/AudioPluginHost/Source/UI/MainHostWindow.h b/extras/AudioPluginHost/Source/UI/MainHostWindow.h
new file mode 100644 (file)
index 0000000..7b64ff3
--- /dev/null
@@ -0,0 +1,112 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#pragma once\r
+\r
+#include "../Filters/FilterGraph.h"\r
+#include "GraphEditorPanel.h"\r
+\r
+\r
+//==============================================================================\r
+namespace CommandIDs\r
+{\r
+   #if ! (JUCE_IOS || JUCE_ANDROID)\r
+    static const int open                   = 0x30000;\r
+    static const int save                   = 0x30001;\r
+    static const int saveAs                 = 0x30002;\r
+    static const int newFile                = 0x30003;\r
+   #endif\r
+    static const int showPluginListEditor   = 0x30100;\r
+    static const int showAudioSettings      = 0x30200;\r
+    static const int aboutBox               = 0x30300;\r
+    static const int allWindowsForward      = 0x30400;\r
+    static const int toggleDoublePrecision  = 0x30500;\r
+}\r
+\r
+ApplicationCommandManager& getCommandManager();\r
+ApplicationProperties& getAppProperties();\r
+bool isOnTouchDevice();\r
+\r
+//==============================================================================\r
+class MainHostWindow    : public DocumentWindow,\r
+                          public MenuBarModel,\r
+                          public ApplicationCommandTarget,\r
+                          public ChangeListener,\r
+                          public FileDragAndDropTarget\r
+{\r
+public:\r
+    //==============================================================================\r
+    MainHostWindow();\r
+    ~MainHostWindow();\r
+\r
+    //==============================================================================\r
+    void closeButtonPressed() override;\r
+    void changeListenerCallback (ChangeBroadcaster*) override;\r
+\r
+    bool isInterestedInFileDrag (const StringArray& files) override;\r
+    void fileDragEnter (const StringArray& files, int, int) override;\r
+    void fileDragMove (const StringArray& files, int, int) override;\r
+    void fileDragExit (const StringArray& files) override;\r
+    void filesDropped (const StringArray& files, int, int) override;\r
+\r
+    void menuBarActivated (bool isActive) override;\r
+\r
+    StringArray getMenuBarNames() override;\r
+    PopupMenu getMenuForIndex (int topLevelMenuIndex, const String& menuName) override;\r
+    void menuItemSelected (int menuItemID, int topLevelMenuIndex) override;\r
+    ApplicationCommandTarget* getNextCommandTarget() override;\r
+    void getAllCommands (Array<CommandID>&) override;\r
+    void getCommandInfo (CommandID, ApplicationCommandInfo&) override;\r
+    bool perform (const InvocationInfo&) override;\r
+\r
+    void tryToQuitApplication();\r
+\r
+    void createPlugin (const PluginDescription&, Point<int> pos);\r
+\r
+    void addPluginsToMenu (PopupMenu&) const;\r
+    const PluginDescription* getChosenType (int menuID) const;\r
+\r
+    bool isDoublePrecisionProcessing();\r
+    void updatePrecisionMenuItem (ApplicationCommandInfo& info);\r
+\r
+    ScopedPointer<GraphDocumentComponent> graphHolder;\r
+\r
+private:\r
+    //==============================================================================\r
+    AudioDeviceManager deviceManager;\r
+    AudioPluginFormatManager formatManager;\r
+\r
+    OwnedArray<PluginDescription> internalTypes;\r
+    KnownPluginList knownPluginList;\r
+    KnownPluginList::SortMethod pluginSortMethod;\r
+\r
+    class PluginListWindow;\r
+    ScopedPointer<PluginListWindow> pluginListWindow;\r
+\r
+    void showAudioSettings();\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainHostWindow)\r
+};\r
diff --git a/extras/AudioPluginHost/Source/UI/PluginWindow.h b/extras/AudioPluginHost/Source/UI/PluginWindow.h
new file mode 100644 (file)
index 0000000..d593ba7
--- /dev/null
@@ -0,0 +1,212 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#pragma once\r
+\r
+#include "../Filters/FilterIOConfiguration.h"\r
+\r
+class FilterGraph;\r
+\r
+//==============================================================================\r
+/**\r
+    A desktop window containing a plugin's GUI.\r
+*/\r
+class PluginWindow  : public DocumentWindow\r
+{\r
+public:\r
+    enum class Type\r
+    {\r
+        normal = 0,\r
+        generic,\r
+        programs,\r
+        audioIO,\r
+        numTypes\r
+    };\r
+\r
+    PluginWindow (AudioProcessorGraph::Node* n, Type t, OwnedArray<PluginWindow>& windowList)\r
+       : DocumentWindow (n->getProcessor()->getName(),\r
+                         LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),\r
+                         DocumentWindow::minimiseButton | DocumentWindow::closeButton),\r
+         activeWindowList (windowList),\r
+         node (n), type (t)\r
+    {\r
+        setSize (400, 300);\r
+\r
+        if (auto* ui = createProcessorEditor (*node->getProcessor(), type))\r
+            setContentOwned (ui, true);\r
+\r
+       #if JUCE_IOS || JUCE_ANDROID\r
+        auto screenBounds = Desktop::getInstance().getDisplays().getTotalBounds (true).toFloat();\r
+\r
+        auto scaleFactor = jmin ((screenBounds.getWidth() - 50) / getWidth(), (screenBounds.getHeight() - 50) / getHeight());\r
+        if (scaleFactor < 1.0f)\r
+            setSize (getWidth() * scaleFactor, getHeight() * scaleFactor);\r
+\r
+        setTopLeftPosition (20, 20);\r
+       #else\r
+        setTopLeftPosition (node->properties.getWithDefault (getLastXProp (type), Random::getSystemRandom().nextInt (500)),\r
+                            node->properties.getWithDefault (getLastYProp (type), Random::getSystemRandom().nextInt (500)));\r
+       #endif\r
+\r
+        node->properties.set (getOpenProp (type), true);\r
+\r
+        setVisible (true);\r
+    }\r
+\r
+    ~PluginWindow()\r
+    {\r
+        clearContentComponent();\r
+    }\r
+\r
+    void moved() override\r
+    {\r
+        node->properties.set (getLastXProp (type), getX());\r
+        node->properties.set (getLastYProp (type), getY());\r
+    }\r
+\r
+    void closeButtonPressed() override\r
+    {\r
+        node->properties.set (getOpenProp (type), false);\r
+        activeWindowList.removeObject (this);\r
+    }\r
+\r
+    static String getLastXProp (Type type)    { return "uiLastX_" + getTypeName (type); }\r
+    static String getLastYProp (Type type)    { return "uiLastY_" + getTypeName (type); }\r
+    static String getOpenProp  (Type type)    { return "uiopen_"  + getTypeName (type); }\r
+\r
+    OwnedArray<PluginWindow>& activeWindowList;\r
+    const AudioProcessorGraph::Node::Ptr node;\r
+    const Type type;\r
+\r
+private:\r
+    float getDesktopScaleFactor() const override     { return 1.0f; }\r
+\r
+    static AudioProcessorEditor* createProcessorEditor (AudioProcessor& processor, PluginWindow::Type type)\r
+    {\r
+        if (type == PluginWindow::Type::normal)\r
+        {\r
+            if (auto* ui = processor.createEditorIfNeeded())\r
+                return ui;\r
+\r
+            type = PluginWindow::Type::generic;\r
+        }\r
+\r
+        if (type == PluginWindow::Type::generic)\r
+            return new GenericAudioProcessorEditor (&processor);\r
+\r
+        if (type == PluginWindow::Type::programs)\r
+            return new ProgramAudioProcessorEditor (processor);\r
+\r
+        if (type == PluginWindow::Type::audioIO)\r
+            return new FilterIOConfigurationWindow (processor);\r
+\r
+        jassertfalse;\r
+        return {};\r
+    }\r
+\r
+    static String getTypeName (Type type)\r
+    {\r
+        switch (type)\r
+        {\r
+            case Type::normal:     return "Normal";\r
+            case Type::generic:    return "Generic";\r
+            case Type::programs:   return "Programs";\r
+            case Type::audioIO:    return "IO";\r
+            default:               return {};\r
+        }\r
+    }\r
+\r
+    //==============================================================================\r
+    struct ProgramAudioProcessorEditor  : public AudioProcessorEditor\r
+    {\r
+        ProgramAudioProcessorEditor (AudioProcessor& p)  : AudioProcessorEditor (p)\r
+        {\r
+            setOpaque (true);\r
+\r
+            addAndMakeVisible (panel);\r
+\r
+            Array<PropertyComponent*> programs;\r
+\r
+            auto numPrograms = p.getNumPrograms();\r
+            int totalHeight = 0;\r
+\r
+            for (int i = 0; i < numPrograms; ++i)\r
+            {\r
+                auto name = p.getProgramName (i).trim();\r
+\r
+                if (name.isEmpty())\r
+                    name = "Unnamed";\r
+\r
+                auto pc = new PropertyComp (name, p);\r
+                programs.add (pc);\r
+                totalHeight += pc->getPreferredHeight();\r
+            }\r
+\r
+            panel.addProperties (programs);\r
+\r
+            setSize (400, jlimit (25, 400, totalHeight));\r
+        }\r
+\r
+        void paint (Graphics& g) override\r
+        {\r
+            g.fillAll (Colours::grey);\r
+        }\r
+\r
+        void resized() override\r
+        {\r
+            panel.setBounds (getLocalBounds());\r
+        }\r
+\r
+    private:\r
+        struct PropertyComp  : public PropertyComponent,\r
+                               private AudioProcessorListener\r
+        {\r
+            PropertyComp (const String& name, AudioProcessor& p)  : PropertyComponent (name), owner (p)\r
+            {\r
+                owner.addListener (this);\r
+            }\r
+\r
+            ~PropertyComp()\r
+            {\r
+                owner.removeListener (this);\r
+            }\r
+\r
+            void refresh() override {}\r
+            void audioProcessorChanged (AudioProcessor*) override {}\r
+            void audioProcessorParameterChanged (AudioProcessor*, int, float) override {}\r
+\r
+            AudioProcessor& owner;\r
+\r
+            JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertyComp)\r
+        };\r
+\r
+        PropertyPanel panel;\r
+\r
+        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgramAudioProcessorEditor)\r
+    };\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginWindow)\r
+};\r
diff --git a/extras/BLOCKS/doxygen/Doxyfile b/extras/BLOCKS/doxygen/Doxyfile
deleted file mode 100644 (file)
index f2bf9fb..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-PROJECT_NAME           = "The BLOCKS SDK"
-
-LAYOUT_FILE            = DoxygenLayout.xml
-
-INPUT                  = build pages
-
-EXAMPLE_PATH           = ../standalone_sdk/examples ../../../examples/BLOCKS ../../../modules
-
-IMAGE_PATH             = images
-
-HTML_HEADER            = header.html
-
-HTML_FOOTER            = footer.html
-
-HTML_EXTRA_STYLESHEET  = stylesheet.css
-
-DISABLE_INDEX          = YES
-
-GENERATE_TREEVIEW      = YES
-
diff --git a/extras/BLOCKS/doxygen/DoxygenLayout.xml b/extras/BLOCKS/doxygen/DoxygenLayout.xml
deleted file mode 100644 (file)
index d6393a7..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-<doxygenlayout version="1.0">
-
-  <navindex>
-    <tab type="pages"   visible="yes" title="Documentation"                 intro="How to use the BLOCKS SDK"/>
-    <tab type="modules" visible="yes" title="JUCE Modules"                  intro="A list of the JUCE modules included in the SDK"/>
-    <tab type="user"    visible="yes" title="Get the JUCE framework"        url="https://github.com/julianstorer/JUCE"/>
-    <tab type="user"    visible="yes" title="Get the standalone BLOCKS SDK" url="https://github.com/WeAreROLI/BLOCKS-SDK"/>
-  </navindex>
-
-  <class>
-    <detaileddescription title="Description"/>
-    <includes visible="$SHOW_INCLUDE_FILES"/>
-    <inheritancegraph visible="$CLASS_GRAPH"/>
-    <collaborationgraph visible="$COLLABORATION_GRAPH"/>
-    <memberdecl>
-      <publicmethods title=""/>
-      <publicstaticmethods title=""/>
-      <publicattributes title=""/>
-      <publicstaticattributes title=""/>
-      <protectedtypes title=""/>
-      <protectedslots title=""/>
-      <protectedmethods title=""/>
-      <protectedstaticmethods title=""/>
-      <protectedattributes title=""/>
-      <protectedstaticattributes title=""/>
-      <packagetypes title=""/>
-      <packagemethods title=""/>
-      <packagestaticmethods title=""/>
-      <packageattributes title=""/>
-      <packagestaticattributes title=""/>
-      <properties title=""/>
-      <events title=""/>
-      <privatetypes title=""/>
-      <privateslots title=""/>
-      <privatemethods title=""/>
-      <privatestaticmethods title=""/>
-      <privateattributes title=""/>
-      <privatestaticattributes title=""/>
-      <nestedclasses visible="yes" title=""/>
-      <publictypes title=""/>
-      <services title=""/>
-      <interfaces title=""/>
-      <publicslots title=""/>
-      <signals title=""/>
-      <friends title=""/>
-      <related title="" subtitle=""/>
-      <membergroups visible="yes"/>
-    </memberdecl>
-    <memberdef>
-      <inlineclasses title=""/>
-      <constructors title=""/>
-      <functions title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <services title=""/>
-      <interfaces title=""/>
-      <related title=""/>
-      <variables title=""/>
-      <properties title=""/>
-      <events title=""/>
-    </memberdef>
-    <allmemberslink visible="yes"/>
-    <usedfiles visible="$SHOW_USED_FILES"/>
-    <authorsection visible="yes"/>
-  </class>
-
-  <group>
-    <detaileddescription title="Description"/>
-    <groupgraph visible="$GROUP_GRAPHS"/>
-    <memberdecl>
-      <nestedgroups visible="yes" title=""/>
-      <dirs visible="yes" title=""/>
-      <files visible="yes" title=""/>
-      <classes visible="yes" title=""/>
-      <functions title=""/>
-      <variables title=""/>
-      <membergroups visible="yes"/>
-    </memberdecl>
-    <memberdef>
-      <pagedocs/>
-      <inlineclasses title=""/>
-      <functions title=""/>
-      <variables title=""/>
-    </memberdef>
-    <authorsection visible="yes"/>
-  </group>
-
-</doxygenlayout>
diff --git a/extras/BLOCKS/doxygen/Makefile b/extras/BLOCKS/doxygen/Makefile
deleted file mode 100644 (file)
index 23d1622..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-SHELL := /bin/bash
-
-INCLUDED_MODULES := juce_audio_basics,juce_audio_devices,juce_blocks_basics,juce_core,juce_events
-
-SOURCE_FILES := $(shell find ../../../modules -type f -name "juce_*.h" -or -name "juce_*.dox"| sed 's/ /\\ /g')
-EXAMPLE_DIRS := ../standalone_sdk/examples ../../../examples/BLOCKS
-EXAMPLE_SOURCE_FILES := $(foreach DIR,$(EXAMPLE_DIRS),$(shell find $(DIR) -type f -name "*.h" -or -name "*.cpp" | sed 's/ /\\ /g'))
-DOCUMENTATION_FILES := $(shell find pages -type f -name "*.dox" | sed 's/ /\\ /g')
-IMAGES := $(shell find images -type f | sed 's/ /\\ /g')
-
-.PHONEY: clean
-
-doc/index.html: build/Doxyfile DoxygenLayout.xml footer.html header.html stylesheet.css $(DOCUMENTATION_FILES) $(EXAMPLE_SOURCE_FILES) $(IMAGES)
-       doxygen $<
-
-build/Doxyfile: ../../../doxygen/Doxyfile Doxyfile build/juce_modules.dox
-       cat ../../../doxygen/Doxyfile Doxyfile > $@
-
-build/juce_modules.dox: ../../../doxygen/process_source_files.py $(SOURCE_FILES)
-       rm -rf build
-       python $< ../../../modules build --subdirs=$(INCLUDED_MODULES)
-
-clean:
-       rm -rf build doc
diff --git a/extras/BLOCKS/doxygen/footer.html b/extras/BLOCKS/doxygen/footer.html
deleted file mode 100644 (file)
index a39221c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<hr class="footer"/>
-<address class="footer"><small>All content &copy ROLI Ltd.</small></address><br/>
-</body>
-</html>
diff --git a/extras/BLOCKS/doxygen/header.html b/extras/BLOCKS/doxygen/header.html
deleted file mode 100644 (file)
index 0ea4e91..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-<!-- HTML header for doxygen 1.8.12-->
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen $doxygenversion"/>
-<meta name="viewport" content="width=device-width, initial-scale=1"/>
-<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
-<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
-<script type="text/javascript" src="$relpath^jquery.js"></script>
-<script type="text/javascript" src="$relpath^dynsections.js"></script>
-
-<script type="text/javascript" src="resize.js"></script>
-<script type="text/javascript" src="navtreedata.js"></script>
-<script type="text/javascript" src="navtree.js"></script>
-<script type="text/javascript">
-  $(document).ready(initResizable);
-</script>
-
-<script type="text/javascript" src="search/searchdata.js"></script>
-<script type="text/javascript" src="search/search.js"></script>
-<script type="text/javascript">
-  $(document).ready(function() { init_search(); });
-</script>
-
-$mathjax
-
-$extrastylesheet
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-
-<!--BEGIN TITLEAREA-->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <!--BEGIN PROJECT_LOGO-->
-  <td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
-  <!--END PROJECT_LOGO-->
-  <!--BEGIN PROJECT_NAME-->
-  <td id="projectalign" style="padding-left: 0.5em;">
-   <div id="projectname">$projectname
-   <!--BEGIN PROJECT_NUMBER-->&#160;<span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
-   </div>
-   <!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
-  </td>
-  <!--END PROJECT_NAME-->
-  <!--BEGIN !PROJECT_NAME-->
-   <!--BEGIN PROJECT_BRIEF-->
-    <td style="padding-left: 0.5em;">
-    <div id="projectbrief">$projectbrief</div>
-    </td>
-   <!--END PROJECT_BRIEF-->
-  <!--END !PROJECT_NAME-->
-  <!--BEGIN DISABLE_INDEX-->
-   <!--BEGIN SEARCHENGINE-->
-   <td>$searchbox</td>
-   <!--END SEARCHENGINE-->
-  <!--END DISABLE_INDEX-->
- </tr>
- </tbody>
-</table>
-</div>
-<!--END TITLEAREA-->
-<!-- end header part -->
diff --git a/extras/BLOCKS/doxygen/images/BlocksDrawing_canvas.JPG b/extras/BLOCKS/doxygen/images/BlocksDrawing_canvas.JPG
deleted file mode 100644 (file)
index 7487c7c..0000000
Binary files a/extras/BLOCKS/doxygen/images/BlocksDrawing_canvas.JPG and /dev/null differ
diff --git a/extras/BLOCKS/doxygen/images/BlocksDrawing_palette.JPG b/extras/BLOCKS/doxygen/images/BlocksDrawing_palette.JPG
deleted file mode 100644 (file)
index fcfe751..0000000
Binary files a/extras/BLOCKS/doxygen/images/BlocksDrawing_palette.JPG and /dev/null differ
diff --git a/extras/BLOCKS/doxygen/images/BlocksMonitor.png b/extras/BLOCKS/doxygen/images/BlocksMonitor.png
deleted file mode 100644 (file)
index 45f3ed8..0000000
Binary files a/extras/BLOCKS/doxygen/images/BlocksMonitor.png and /dev/null differ
diff --git a/extras/BLOCKS/doxygen/images/BlocksSynth_grid.JPG b/extras/BLOCKS/doxygen/images/BlocksSynth_grid.JPG
deleted file mode 100644 (file)
index a7626f2..0000000
Binary files a/extras/BLOCKS/doxygen/images/BlocksSynth_grid.JPG and /dev/null differ
diff --git a/extras/BLOCKS/doxygen/images/BlocksSynth_waveshape.gif b/extras/BLOCKS/doxygen/images/BlocksSynth_waveshape.gif
deleted file mode 100644 (file)
index e472685..0000000
Binary files a/extras/BLOCKS/doxygen/images/BlocksSynth_waveshape.gif and /dev/null differ
diff --git a/extras/BLOCKS/doxygen/pages/juce_connecting_blocks.dox b/extras/BLOCKS/doxygen/pages/juce_connecting_blocks.dox
deleted file mode 100644 (file)
index 7d720fa..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/**\r
-@page connecting_blocks Connecting BLOCKS\r
-\r
-Lightpads can be conected to a computer either via USB or Bluetooth, and Control Blocks can be connected via Bluetooth or by snapping to an already connected Lightpad.\r
-Both devices communicate with your computer using System Exclusive (SysEx) MIDI messages.\r
-\r
-@section usb USB\r
-\r
-To connect a Lightpad to your computer over USB, you need to insert a USB-C cable into the top of the device and connect it to a USB port on your computer.\r
-When powered on by pressing the power button on the bottom edge, you will be able to send and receive data from the block over the USB connection.\r
-\r
-@section bluetooth Bluetooth\r
-\r
-The power button also functions as a toggle for the Bluetooth connection - when the blue light on the button is illuminated, the device is able to connect via Bluetooth and send and receive MIDI data.\r
-Pressing this button will turn the light off and disable the Bluetooth functionality.\r
-Currently MIDI over Bluetooth is only supported on Mac OS.\r
-\r
-@subsection mac_bluetooth MacOS\r
-\r
-To connect a BLOCKS device via Bluetooth on MacOS, follow these steps:\r
-\r
-- Open the "Audio Midi Setup" application (found in Applications/Utilities)\r
-- Click on the menu item: Window -> Show MIDI Studio\r
-- Double-click on the "Bluetooth" icon in the MIDI Studio window\r
-- Click the "Connect" button next to the block you want to connect to\r
-- Your device should show up in the MIDI Studio window with a Bluetooth icon and can now send and receive MIDI data over Bluetooth\r
-\r
-@section connecting_blocks_to_each_other Connecting BLOCKS together\r
-\r
-Lightpad and Control Blocks can be connected together in any number of combinations via their DNA edge connectors, sharing a common connection to your computer.\r
-To do this, simply snap your devices together and the magnetic connectors will handle the rest.\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_controlling_control_buttons.dox b/extras/BLOCKS/doxygen/pages/juce_controlling_control_buttons.dox
deleted file mode 100644 (file)
index 2712e54..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/**\r
-@page controlling_control_buttons Controlling control buttons\r
-\r
-In addition to sending button pressed and button released events, ControlButton objects can allow your application code to change the colour of the LED behind the corresponding physical button on a BLOCKS device.\r
-\r
-An array of pointers to the available %ControlButton objects can be obtained from the Block::getButtons method of a Block---see the @ref discovering_blocks section for details of how to obtain a %Block object.\r
-Once you have a %ControlButton, the functions involving the LED are ControlButton::hasLight and ControlButton::setLightColour, which are descriptively named.\r
-A code snippet showing how to turn all the available buttons of a %Block red is shown below.\r
-@code{.cpp}\r
-void setAllButtonsRed (Block& block)\r
-{\r
-    for (auto button : block->getButtons())\r
-        if (button->hasLight())\r
-            button->setLightColour (Colours::red);\r
-}\r
-@endcode\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_controlling_led_grids.dox b/extras/BLOCKS/doxygen/pages/juce_controlling_led_grids.dox
deleted file mode 100644 (file)
index b9e1a04..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/**\r
-@page controlling_led_grids Controlling LED grids\r
-\r
-@section basic_usage Basic usage\r
-\r
-An LED grid on a BLOCKS device can be controlled via an LEDGrid object, which can be obtained from the Block::getLEDGrid function of a Block---see the @ref discovering_blocks section for details of how to obtain a %Block object.\r
-\r
-Using an LED grid requires an LEDGrid::Program to operate the LEDs.\r
-This program specifies some code to run on the device, and can also provide methods to be called from your application which can comminucate with the code running on the device via a block of shared memory.\r
-The code which runs on the device must be specified using @ref the_littlefoot_language, which is described in the corresponding section.\r
-However, for a very wide range of applications, the BitmapLEDProgram provided with the BLOCKS SDK is sufficient and you will not need to create your own.\r
-Using a %BitmapLEDProgram to change the colour of LEDs is demonstated below.\r
-\r
-@code{.cpp}\r
-// This should be called when doing the initial configuration of your application.\r
-void setBitmapLEDProgram (Block& block)\r
-{\r
-    if (auto grid = block->getLEDGrid())\r
-        grid->setProgram (new BitmapLEDProgram (*grid));\r
-}\r
-\r
-// Once a BitmapLEDProgram is loaded we can use its setLED method to change the\r
-// colour of LEDs on the corresponding device.\r
-void setLED (Block& block, int x, int y, Colour c)\r
-{\r
-    if (auto grid = block->getLEDGrid())\r
-        if (auto program = dynamic_cast<BitmapLEDProgram*> (grid->getProgram()))\r
-            program->setLED (x, y, c);\r
-}\r
-@endcode\r
-\r
-@section advanced_usage Advanced Usage\r
-\r
-Using a custom %LEDGrid::Program allows more precise control over the operation of the LEDs.\r
-The code which will actually execute on the device, returned by your overriden LEDGrid::Program::getLittleFootProgram() function, must be specified in the LittleFoot language.\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_controlling_led_strips.dox b/extras/BLOCKS/doxygen/pages/juce_controlling_led_strips.dox
deleted file mode 100644 (file)
index 8d7549e..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/**\r
-@page controlling_led_strips Controlling LED strips\r
-\r
-Control Blocks have a strip of LEDs which can be controlled via an LEDRow object.\r
-\r
-A pointer to an %LEDRow object can be obtained from the Block::getLEDRow method of a Block---see the @ref discovering_blocks section for details of how to obtain a %Block object.\r
-Once you have an %LEDRow there are a few functions that you can use to interact with the strip of LEDs on a device.\r
-A code snippet showing how to turn the whole strip of LEDs on a %Block orange is shown below.\r
-@code{.cpp}\r
-void setWholeLEDRowOrange (Block& block)\r
-{\r
-    if (auto ledRow = block->getLEDRow())\r
-        for (int i = 0; i < ledRow.getNumLEDs(); ++i)\r
-            ledRow.setLEDColour (i, Colours::orange);\r
-}\r
-@endcode\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_discovering_blocks.dox b/extras/BLOCKS/doxygen/pages/juce_discovering_blocks.dox
deleted file mode 100644 (file)
index 33ccc07..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/**\r
-@page discovering_blocks Discovering BLOCKS\r
-\r
-Any BLOCKS application would be pretty limited without the ability to discover the BLOCKS that are connected to your computer.\r
-This page gives an overview of the classes and methods available to aid BLOCKS discovery and provides sample code for getting notifications of any connections or disconnections.\r
-\r
-@section the_block_topology_object The BlockTopology object\r
-\r
-Groups of connected Lightpad and Control Blocks are described by a BlockTopology.\r
-\r
-A %BlockTopology contains an array of references to Block objects, which provide access to Lightpad and Control %Block functionality, and an array of BlockDeviceConnection objects, which describe the connections between devices.\r
-Once you have a %BlockTopology you have all the information required to visualise and interact with your Lightpads and Control Blocks.\r
-For more information about using %Block objects see the @ref the_block_object section.\r
-\r
-For Lightpads and Control Blocks a %BlockTopology can be obtained from a PhysicalTopologySource.\r
-\r
-@section the_physical_topology_source_object The PhysicalTopologySource object\r
-\r
-The current topology is provided by a %PhysicalTopologySource.\r
-When instantiated, a %PhysicalTopologySource monitors for any connections from your computer to any Lightpad and Control Blocks and the PhysicalTopologySource::getCurrentTopology() method returns the current %BlockTopology.\r
-\r
-In an environment where Lightpad and Control can be connected and disconnected dynamically it is convenient to register your code for <code>topologyChanged()</code> callbacks from a %PhysicalTopologySource.\r
-Then, when the current %BlockTopology changes, your application is able to react to the new configuration.\r
-You can do this by inheriting from the TopologySource::Listener class and registering as a listener to a %PhysicalTopologySource object.\r
-When you inherit from %TopologySource::Listener you must override the pure virtual method TopologySource::Listener::topologyChanged(), which is then called by a %PhysicalTopologySource on topology changes when you register as a listener.\r
-A simple example is shown below.\r
-\r
-BlockFinder.h:\r
-@include BlockFinder/BlockFinder.h\r
-\r
-BlockFinder.cpp:\r
-@include BlockFinder/BlockFinder.cpp\r
-\r
-When instantiated this class simply monitors for changes to the connected Lightpad and Control Blocks and prints some information about them to stdout.\r
-Once you have the current %BlockTopology object you have access to the available %Block objects and can start to interact with them.\r
-A more complex application would probably do much more in the <tt>topologyChanged()</tt> method---see the @ref example_applications page.\r
-\r
-@section the_block_object The Block object\r
-\r
-A Block object is the main entry point for communicating between your application and any Lightpad and Control Blocks that are connected to your computer.\r
-\r
-All the different %Block types are subclasses of %Block so they provide the same interface (see the %Block class documentation).\r
-About half of the %Block public member functions return information about the physical device it represents.\r
-In the example code above you can see that we use some of these methods to query each %Block about its current status.\r
-The more interesting %Block methods return pointers to objects you can use to control and receive events from individual BLOCKS.\r
-More detail about these methods can be obtained from the following pages:\r
-\r
-@ref getting_touch_events\r
-\r
-@ref getting_control_button_events\r
-\r
-@ref controlling_led_grids\r
-\r
-@ref controlling_led_strips\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_downloading_the_sdk.dox b/extras/BLOCKS/doxygen/pages/juce_downloading_the_sdk.dox
deleted file mode 100644 (file)
index 207c80f..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/**\r
-@page downloading_the_sdk Downloading the SDK\r
-\r
-The BLOCKS SDK is distributed as part of the <a href="https://www.juce.com/">JUCE framework</a>, which can be obtained from GitHub <a href="https://github.com/julianstorer/JUCE">here</a>.\r
-The JUCE repository also contains the code for the @ref example_applications, which require the JUCE framework to compile.\r
-Whilst you don't need to know anything about JUCE to build the examples using the supplied Visual Studio/Xcode/etc projects, it will probably be worthwhile reading a brief introduction to JUCE, which can be found <a href="https://www.juce.com/learn/getting-started">here</a>.\r
-\r
-You can also download the standalone BLOCKS SDK from GitHub <a href="https://github.com/WeAreROLI/BLOCKS-SDK">here</a>.\r
-This is a stripped down version of what JUCE provides, including only the features required for the SDK.\r
-Using this version of the SDK is much more complicated but may be more suitable for integrating BLOCKS into an existing application.\r
-More details are provided in the @ref the_standalone_blocks_sdk section.\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_example_applications.dox b/extras/BLOCKS/doxygen/pages/juce_example_applications.dox
deleted file mode 100644 (file)
index 10b9623..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/**\r
-@page example_applications Example Applications\r
-\r
-@section downloading_the_example_code Downloading the example code\r
-\r
-These example applications demonstrate the functionality of the BLOCKS SDK.\r
-\r
-The example applications are all distributed as part of the <a href="https://www.juce.com/">JUCE framework</a>, which can be obtained from GitHub <a href="https://github.com/julianstorer/JUCE">here</a>.\r
-You will find the examples in the <tt>JUCE/examples/BLOCKS/</tt> directory.\r
-Each example comes with projects for Visual Studio, Xcode, etc in the <tt>Builds</tt> subdirectory or each example directory, and these should open, compile and run without any trouble in the respective IDEs.\r
-\r
-A quick guide to getting up and running with JUCE can be found <a href="https://www.juce.com/learn/getting-started">here</a>.\r
-\r
-<h1>Overview</h1>\r
-\r
-@subpage example_blocks_monitor\r
-\r
-BlocksMonitor is a simple JUCE application that shows currently connected Lightpad and Control %Block devices and visualises touches and button presses.\r
-It also displays some basic information about the Blocks.\r
-\r
-@subpage example_blocks_drawing\r
-\r
-BlocksDrawing is a JUCE application that allows you to use your Lightpad as a drawing surface.\r
-You can choose from a palette of 9 base colours and paint them on the 15x15 LED grid, blending between colours using touch pressure.\r
-\r
-@subpage example_blocks_synth\r
-\r
-BlocksSynth is a JUCE application that turns your Lightpad into a simple monophonic synthesiser capable of playing 4 different waveshapes - sine, square, sawtooth and triangle.\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_example_blocks_drawing.dox b/extras/BLOCKS/doxygen/pages/juce_example_blocks_drawing.dox
deleted file mode 100644 (file)
index 9896685..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/**\r
-@page example_blocks_drawing BlocksDrawing\r
-\r
-In order to compile and run this application you need to first download the <a href="https://www.juce.com/">JUCE framework</a>, which can be obtained from GitHub <a href="https://github.com/julianstorer/JUCE">here</a>.\r
-\r
-@section blocks_drawing_introduction Introduction\r
-\r
-BlocksDrawing is a JUCE application that allows you to use your Lightpad as a drawing surface. You can choose from a palette of 9 base colours and paint them on the 15x15 LED grid, blending between colours using touch pressure.\r
-\r
-Navigate to the <tt>JUCE/examples/BLOCKS/BlocksDrawing/Builds/</tt> directory and open the code project in your IDE of choice. Run the application and connect your Lightpad (if you do not know how to do this, see @ref connecting_blocks) - it should now display a 3x3 grid of colours to choose from. Touch a colour to set it as the current brush colour and then press the mode button to switch to canvas mode where you will be presented with a blank touch surface. Touch anywhere on the LED grid to start painting and use the pressure of your touch to control how bright the colour is. Try painting over an already painted LED to increase its brightness and blend between different colours by doing this with a different brush colour. To clear the canvas and start over, double-click the mode button.\r
-\r
-The concept of a BLOCKS topology and the methods for receiving callbacks from a Block object are covered in the @ref example_blocks_monitor example and this tutorial will cover the methods in the API for displaying grids and setting LEDs on the Lightpad.\r
-\r
-@section blocks_drawing_led_grid The LEDGrid Object\r
-\r
-Lightpads have a 15x15 LED grid which can be accessed and controlled through the LEDGrid object, a pointer to which is returned by the Block::getLEDGrid() method (for more details on how the %LEDGrid object operates, see @ref controlling_led_grids). In the <code>topologyChanged()</code> method of <code>MainComponent</code> this %LEDGrid pointer is passed to the <code>setLEDProgram()</code> method, which sets the LEDGrid::Program to either a DrumPadGridProgram or BitmapLEDProgram, depending on the selected mode.\r
-\r
-@section blocks_drawing_colour_palette Colour Palette\r
-\r
-In the colour palette mode the Lightpad displays a 3x3 grid of colours, constructed using the %DrumPadGridProgram class. A %DrumPadGridProgram pointer called <code>colourPaletteProgram</code> is declared as a private member variable of <code>MainComponent</code> and in the <code>MainComponent::setLEDProgram()</code> method this is set to point to a new %DrumPadGridProgram object and is passed the %LEDGrid object of the Lightpad in its constructor. After the program has been initialised, it is passed to the LEDGrid to display using the LEDGrid::setProgram() method and the layout of the grid is set up using the DrumPadGridProgram::setGridFills() method. This function takes 3 arguments: the number of rows, number of columns and an array of DrumPadGridProgram::GridFill objects containing a <code>GridFill</code> for each pad that controls its colour and fill type. The <code>ColourGrid</code> struct in MainComponent.h contains all of this information and handles the construction of the <code>GridFill</code> array in the <code>ColourGrid::constructGridFillArray()</code> method. An instance of this object called <code>layout</code> is declared as a member variable of <code>MainComponent</code> to easily change how the grid looks. The <code>ColourGrid::setActiveColourForTouch()</code> method is called in the <code>MainComponent::touchChanged()</code> callback and is used to determine which brush colour has been selected based on a Touch coordinate from the Lightpad.\r
-\r
-\image html BlocksDrawing_palette.JPG "Colour palette mode"\r
-\r
-@section blocks_drawing_canvas Canvas\r
-\r
-In canvas mode, the %LEDGrid program is set to an instance of %BitmapLEDProgram and uses the BitmapLEDProgram::setLED() method to set individual LEDs on the Lightpad to a particular colour. The <code>ActiveLED</code> struct declared in the private section of <code>MainComponent</code> is used to keep track of which LEDs are on and their colour and brightness. <code>MainComponent</code> contains an %Array of these objects called <code>activeLeds</code>.\r
-In the <code>MainComponent::setLEDProgram()</code> method the program is set up and passed to the %LEDGrid object the same way as in the colour palette mode but the <code>MainComponent::redrawLEDs()</code> method is also called which iterates over the <code>activeLeds</code> array and sets the appropriate LEDs on the Lightpad so the LED states persist between mode switches. When a Touch is received in the <code>MainComponent::touchChanged()</code> callback the <code>MainComponent::drawLEDs()</code> method is called with 4 arguments: x and y coordinates, touch pressure and brush colour. This method iterates over the <code>activeLed</code> array and checks to see if there is an active LED at the given coordinate. If it is blank, an <code>ActiveLED</code> object is created and added to the array with the given coordinates and colour using touch pressure for brightness. If there is already an active LED at the coordinate, the colour of that LED will be blended with the current brush colour, the proportion of which is determined by the touch pressure.\r
-\r
-\image html BlocksDrawing_canvas.JPG "Unleash your inner Picasso!"\r
-\r
-@section blocks_drawing_summary Summary\r
-\r
-This tutorial and the accompanying code project have introduced the %LEDGrid object and shown how to use the %LEDGrid::Program object to display basic grids and set individual LEDs on the Lightpad.\r
-\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_example_blocks_monitor.dox b/extras/BLOCKS/doxygen/pages/juce_example_blocks_monitor.dox
deleted file mode 100644 (file)
index 0d53be7..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/**\r
-@page example_blocks_monitor BlocksMonitor\r
-\r
-In order to compile and run this application you need to first download the <a href="https://www.juce.com/">JUCE framework</a>, which can be obtained from GitHub <a href="https://github.com/julianstorer/JUCE">here</a>.\r
-\r
-@section blocks_monitor_introduction Introduction\r
-\r
-BlocksMonitor is a simple JUCE application that shows currently connected Lightpad and Control %Block devices and visualises touches and button presses. It also displays some basic information about the Blocks.\r
-\r
-Navigate to the <tt>JUCE/examples/BLOCKS/BlocksMonitor/Builds/</tt> directory and open the code project in your IDE of choice. Run the application and connect your Blocks (if you do not know how to do this, see @ref connecting_blocks). Any devices that you have connected should now show up in the application window and this display will be updated as you add and remove Blocks. Lightpads are represented as a black square and will display the current touches as coloured circles, the size of which depend on the touch pressure, and Control Blocks are shown as rectangles containing the LED row and clickable buttons on the hardware. If you hover the mouse cursor over a %Block, a tooltip will appear displaying the name, UID, serial number and current battery level.\r
-\r
-\image html BlocksMonitor.png "The BlocksMonitor application with a Lightpad and 3 Control Blocks connected"\r
-\r
-@section blocks_monitor_topology Topology\r
-\r
-One of the fundamental concepts of the BLOCKS API is topology - a topology is a set of physically connected Blocks and the connections between them. Knowing when the topology has changed and accessing a data structure containing the current topology is the basis of any Blocks application.\r
-\r
-To access the current topology, <code>MainComponent</code> inherits from the TopologySource::Listener base class and implements the TopologySource::Listener::topologyChanged() method, a callback which is used to inform listeners when any physical devices have been added or removed. In order to receive these callbacks, <code>MainComponent</code> contains an instance of the PhysicalTopologySource class and registers itself as a listener to this object in its constructor. When the <code>topologyChanged()</code> method is called, this object can be used to access the updated topology through the PhysicalTopologySource::getCurrentTopology() method which returns a BlockTopology struct containing an array of currently connected Block objects and an array of BlockDeviceConnection structs representing the connections between them.\r
-\r
-@section blocks_monitor_block_object The Block Object\r
-\r
-The array of %Block objects contained in the %BlockTopology struct can be used to access individual %Block objects and determine their type using the Block::getType() method. The application uses this information to construct an on-screen representation of the currently connected Blocks by creating either a <code>LightpadComponent</code> or <code>ControlBlockComponent</code> object for each %Block in the current topology. Both of these classes derive from <code>BlockComponent</code>, a relatively simple base class that contains some virtual functions for painting the %Block on screen and handling callbacks from the touch surface and/or buttons on the %Block. In its constructor, <code>BlockComponent</code> takes a pointer to the %Block object that it represents and adds itself as a listener to the touch surface (if it is a Lightpad) and buttons using the Block::getTouchSurface() and Block::getButtons() methods, respectively. It inherits from the TouchSurface::Listener and ControlButton::Listener classes and overrides the TouchSurface::Listener::touchChanged(), ControlButton::Listener::buttonPressed() and ControlButton::Listener::buttonReleased() methods to call its own virtual methods, which are implemented by the <code>LightpadComponent</code> and <code>ControlBlockComponent</code> classes to update the on-screen components.\r
-\r
-To visualise touches on the Lightpad, <code>LightpadComponent</code> contains an instance of the TouchList class called <code>touches</code> and calls the TouchList::updateTouch() method whenever it receives a touch surface listener callback in the <code>LightpadComponent::handleTouchChange()</code> method. The <code>LightpadBlock::paint()</code> method then iterates over the current TouchSurface::Touch objects in the %TouchList and visualises them on the component at 25Hz.\r
-\r
-The <code>ControlBlockComponent</code> class represents a generic Control %Block with 15 LEDs, 8 circular buttons and 1 rounded rectangular button. When a button is pressed on the physical Control %Block, the <code>BlockComponent::handleButtonPressed()</code> function is called and this class uses the ControlButton::ButtonFunction variable to determine which button was pressed and should be activated on the on-screen component. The same process is repeated for when the button is released. This class also overrides the <code>BlockComponent::handleBatteryLevelUpdate()</code> method to update which LEDs should be on based on the battery level, which is accessed in the <code>BlockComponent</code> base class using the Block::getBatteryLevel() and Block::isBatteryCharging() methods.\r
-\r
-These callback methods are a simple and powerful way to get user input from the Blocks and use this data to drive some process in your application. In this example, the input is simply mirrored on the screen but it could be used to control any number of things such as audio synthesis (see the @ref example_blocks_synth example) and graphics (see the @ref example_blocks_drawing example).\r
-\r
-@section blocks_monitor_connections Blocks Connections\r
-\r
-The %BlockTopology struct returned by the <code>%PhysicalTopologySource::getCurrentTopology()</code> method also contains an array of BlockDeviceConnection objects representing all the current DNA port connections between Blocks in the topology. A single %BlockDeviceConnection struct describes a physical connection between two ports on two Blocks and contains a Block::UID and Block::ConnectionPort object for each of the two devices.\r
-\r
-This information is used to calculate the position and rotation of each connected %Block and update the corresponding <code>topLeft</code> and <code>rotation</code> member variables of its <code>BlockComponent</code> so that the correct topology is displayed on the screen. The <code>topLeft</code> variable is a Point that describes the position of the top left of the <code>BlockComponent</code> in terms of logical device units relative to the top left of the master %Block at Point (0, 0). Initially, all <code>BlockComponent</code> instances have the <code>topLeft</code> position (0, 0) and the <code>MainComponent::positionBlocks()</code> method iterates first over all of the Blocks connected to the master %Block and then any remaining Blocks and calculates the correct <code>topLeft</code> %Point and <code>rotation</code> for each using the array of %BlockDeviceConnection objects. Then, in the <code>MainComponent::resized()</code> method these attributes are used to correctly position the components.\r
-\r
-\r
-@section blocks_monitor_summary Summary\r
-\r
-This tutorial and the accompanying code has introduced the %BlockTopology and %Block objects, and demonstrated how to receive callbacks from connected Blocks when the touch surface or buttons are pressed, allowing you to use this input in your own applications.\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_example_blocks_synth.dox b/extras/BLOCKS/doxygen/pages/juce_example_blocks_synth.dox
deleted file mode 100644 (file)
index eff61f4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/**\r
-@page example_blocks_synth BlocksSynth\r
-\r
-In order to compile and run this application you need to first download the <a href="https://www.juce.com/">JUCE framework</a>, which can be obtained from GitHub <a href="https://github.com/julianstorer/JUCE">here</a>.\r
-\r
-@section blocks_synth_introduction Introduction\r
-\r
-BlocksSynth is a JUCE application that turns your Lightpad into a simple monophonic synthesiser capable of playing 4 different waveshapes - sine, square, sawtooth and triangle.\r
-\r
-Navigate to the <tt>JUCE/examples/BLOCKS/BlocksSynth/Builds/</tt> directory and open the code project in your IDE of choice. Run the application and connect your Lightpad (if you do not know how to do this, see @ref connecting_blocks) - it should now display a simple 5x5 grid where each pad plays a note in the chromatic scale using a sine wave starting from the bottom-left (C3). It is possible to play any of the 25 notes but for ease of use tonics (the root note of the scale) are highlighted in white and notes in the C-major scale are highlighted in green. When a note has been played it is possible to change the amplitude using touch pressure and to pitch bend between adjacent notes by sliding left and right. Pressing the mode button on the Lightpad will change to the waveshape selection screen where the currently selected waveshape is rendered on the LEDs and you can switch between the 4 different waveshapes by touching anywhere on the %Block surface.\r
-\r
-The concept of a BLOCKS topology and the methods for receiving callbacks from the Block object are covered in the @ref example_blocks_monitor example and the basic methods for displaying grids and setting LEDs on the %Block are covered in the @ref example_blocks_drawing example. This example will cover how to render custom programs on the LEDGrid using the Littlefoot language and how to do some simple audio synthesis using data from the Lightpad.\r
-\r
-@section blocks_synth_note_grid Note Grid\r
-\r
-In the synthesiser mode the Lightpad displays a 5x5 grid constructed using the DrumPadGridProgram class. The <code>SynthGrid</code> struct in <tt>MainComponent.h</tt> handles the setup and layout of this grid and sets the colours of the pads to white for tonics, green for notes in the C major scale and black for notes that are not in the C major scale. The <code>ColourGrid::getNoteNumberForPad()</code> method is called in the <code>MainComponent::touchChanged()</code> callback and returns the corresponding MIDI note number for a Touch coordinate on the Lightpad. This note number is then passed to the <code>Audio</code> class to be played on the synthesiser.\r
-\r
-\image html BlocksSynth_grid.JPG "Synthesiser note grid"\r
-\r
-@section blocks_synth_waveshape_display Waveshape Display\r
-\r
-In the waveshape selection mode the LEDGrid::Program is set to an instance of the WaveshapeProgram class, which is contained in the <code>WaveshapeProgram.h</code> file. This class inherits from %LEDGrid::Program so that it can be loaded onto the %LEDGrid and its LittleFoot program can be executed on the Lightpad. The class itself is relatively simple and contains a method to set which waveshape should be displayed, a method to load the coordinates for each of the four waveshapes into the heap and two pure virtual methods overridden from %LEDGrid::Program - LEDGrid::Program::getLittleFootProgram() and LEDGrid::Program::getHeapSize(). The heap is the area of shared memory that is used by the program to communicate with the host computer and the size of this memory is set using the <code>getHeapSize()</code> method. In the private section of <code>WaveshapeProgram</code> the structure of the shared data heap is laid out with variables containing the offsets for each section and the <code>totalDataSize</code> variable contains the total size (in bytes) that is required and is returned by the <code>WaveshapeProgram::getHeapSize()</code> method. The heap contains space for a variable that determines which waveshape type to display and the Y coordinates for 1.5 cycles of each of the four waveshapes.\r
-\r
-The <code>WaveshapeProgram::getLittleFootProgram()</code> method returns the LittleFoot program that will be executed on the BLOCKS device. The <code>repaint()</code> method of this program is called at approximately 25Hz and is used to draw the moving waveshape on the LEDs of the Lightpad. Each time this method is called, it clears the LEDs by setting them all to black then calculates the heap offset based on the waveshape type that has been set and uses a <code>for</code> loop to iterate over the 15 LEDs on the X-axis and draw an LED 'circle' using the <code>drawLEDCircle()</code> method at the corresponding Y coordinate for the selected waveshape. The read position of the heap is offset using the <code>yOffset</code> variable which is incremented each <code>repaint()</code> call and wraps back around when the end of the heap section for the selected waveshape is reached to draw a 'moving' waveshape.\r
-\r
-\image html BlocksSynth_waveshape.gif "A sine wave dispayed in the waveshape selection mode"\r
-\r
-@section blocks_synth_audio Audio\r
-\r
-The <code>Audio</code> class handles the audio synthesis for this application and overrides the AudioIODeviceCallback::audioDeviceIOCallback() method to call the Synthesiser::renderNextBlock() method of a Synthesiser object. This object is initialised to be capable of rendering sine, square, sawtooth and triangle waves on separate MIDI channels in the constructor of <code>Audio</code>, and <code>Audio</code> contains methods for sending note on, note off, channel pressure and pitch wheel messages to the Synthesiser. When a note is triggered on the Lightpad, the <code>Audio::noteOn()</code> method is called with 3 arguments: a MIDI channel corresponding to the waveshape that should be generated, a MIDI note number and an initial velocity. Whilst the note is playing, the amplitude and pitch are modulated by calling the <code>Audio::pressureChange()</code> and <code>Audio::pitchChange()</code> methods from the <code>MainComponent::touchChanged()</code> callback. The pressure value of the Touch instance is used to directly control the Synthesiser amplitude and the distance from the initial note trigger on the X-axis of the Lightpad is scaled to +/-1.0 and used to modulate the frequency of the currently playing note.\r
-The <tt>Oscillators.h</tt> file contains the waveshape rendering code. It contains an <code>Oscillator</code> base class which inherits from SynthesiserVoice and has a pure virtual <code>Oscillator::renderWaveShape()</code> method that is overridden by subclasses to render the 4 different waveshapes.\r
-\r
-@section blocks_synth_summary Summary\r
-\r
-This tutorial and the accompanying code project have expanded on the topics covered by previous tutorials, showing you how to display more complex, custom programs on the %LEDGrid using the LittleFoot language and how to control simple audio synthesis parameters using the Lightpad.\r
-\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_getting_control_button_events.dox b/extras/BLOCKS/doxygen/pages/juce_getting_control_button_events.dox
deleted file mode 100644 (file)
index 8b762a9..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/**\r
-@page getting_control_button_events Getting control button events\r
-\r
-Control button events are communicated from Lightpad and Control Blocks to your application via ControlButton objects.\r
-\r
-You can obtain an array of %ControlButton pointers associated with a specific Lightpad or Control %Block from its corresponding Block object using the Block::getButtons method---see the @ref discovering_blocks page for an example of how to obtain %Block objects.\r
-Each pointer to a %ControlButton will be valid for the lifetime of the %Block object.\r
-\r
-Once you have a %ControlButton you must register as a ControlButton::Listener to receive button pressed and button released callbacks.\r
-The process for doing this is to have one of your application's classes inherit from %ControlButton::Listener and override the pure virtual methods ControlButton::Listener::buttonPressed and ControlButton::Listener::buttonReleased.\r
-Then, when you register your derived class as a listener to a particular %ControlButton, your overriden methods will be called when the corresponding button is pressed and released.\r
-\r
-Registering a class derived from %ControlButton::Listener with multiple %ControlButton objects is done as follows:\r
-@code{.cpp}\r
-class ControlButtonListenerExample : public ControlButton::Listener\r
-{\r
-public:\r
-    ControlButtonListenerExample (Block& block)\r
-    {\r
-        for (auto button : block->getButtons())\r
-            button->addListener (this);\r
-    }\r
-\r
-    virtual void buttonPressed (ControlButton&, sourceControlButton, Block::Timestamp timestamp) override\r
-    {\r
-        // Do something when the sourceControlButton is pressed!\r
-    }\r
-\r
-    virtual void buttonReleased (ControlButton&, sourceControlButton, Block::Timestamp timestamp) override\r
-    {\r
-        // Do something when the sourceControlButton is released!\r
-    }\r
-};\r
-@endcode\r
-\r
-When your overriden <code>buttonPressed</code> or <code>buttonReleased</code> methods are called you have access to two paramters: a reference to the %ControlButton that generated this event and timestamp for the event.\r
-\r
-You will find multiple examples of control button listeners in the @ref example_applications pages.\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_getting_touch_events.dox b/extras/BLOCKS/doxygen/pages/juce_getting_touch_events.dox
deleted file mode 100644 (file)
index 6a02a61..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/**\r
-@page getting_touch_events Getting touch events\r
-\r
-Touch events are communicated from BLOCKS devices to your application code via TouchSurface objects.\r
-\r
-You can obtain a pointer to the %TouchSurface associated with a specific BLOCKS device from its corresponding Block object using the Block::getTouchSurface() method---see the @ref discovering_blocks page for an example of how to obtain %Block objects.\r
-For devices without a touch surface (such as the Control Block) this method will return <code>nullptr</code>, but if the device is capable of sending touch events then the pointer to the %TouchSurface will be valid for the lifetime of the %Block object.\r
-\r
-Once you have a %TouchSurface you must register as a TouchSurface::Listener to get touch events.\r
-The process for doing this is to have one of your application's classes inherit from %TouchSurface::Listener and override the pure virtual method TouchSurface::Listener::touchChanged.\r
-Then, when you register your derived class as a listener to a particular %TouchSurface, your overriden method will be called when the corresponding device is touched.\r
-\r
-A safe way of registering a class derived from %TouchSurface::Listener with a %TouchSurface is as follows.\r
-@code{.cpp}\r
-class TouchSurfaceListenerExample : public TouchSurface::Listener\r
-{\r
-public:\r
-    TouchSurfaceListenerExample (Block& block)\r
-    {\r
-        if (auto touchSurface = block->getTouchSurface())\r
-            touchSurface->addListener (this);\r
-    }\r
-\r
-    virtual void touchChanged (TouchSurface& sourceTouchSurface, const TouchSurface::Touch& touchEvent) override\r
-    {\r
-        // Do something with touchEvent here!\r
-    }\r
-};\r
-@endcode\r
-\r
-When your overriden <code>touchChanged</code> method is called you have access to two paramters: a reference to the %TouchSurface that generated this event and a reference to a TouchSurface::Touch.\r
-The %TouchSurface::Touch class contains member variables describing the postion, pressure, velocity, timestamp and more.\r
-\r
-You will find multiple examples of using TouchSurfaces in the @ref example_applications pages.\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_main.dox b/extras/BLOCKS/doxygen/pages/juce_main.dox
deleted file mode 100644 (file)
index 4b64c38..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/**\r
-@mainpage Documentation\r
-\r
-Welcome to the BLOCKS SDK documentation.\r
-<br>\r
-\r
-Here you will find all the information required to start creating BLOCKS applications.\r
-A brief summary of the main sections is below.\r
-\r
-<br>\r
-@subpage downloading_the_sdk\r
-\r
-This section describes how to obtain the SDK source code, either via the <a href="https://github.com/julianstorer/JUCE">JUCE framework</a> or @ref the_standalone_blocks_sdk.\r
-\r
-<br>\r
-@subpage connecting_blocks\r
-\r
-Lightpad and Control Blocks communicate with a computer over USB-C or Bluetooth, and communicate with each other via magnetic connections on their sides.\r
-This section contains instructions for configuring your setup so that all the components can communicate with each other.\r
-\r
-<br>\r
-@subpage discovering_blocks\r
-\r
-Once you have connected your device to your computer you need to be able to discover it from your application.\r
-This section outlines the procedure for Lightpad and Control %Block discovery and provides some simple example code which monitors for new connections.\r
-\r
-<br>\r
-@subpage getting_touch_events\r
-\r
-This section explains how to capture touch events from a compatible device and, building on the @ref discovering_blocks section, displays some example code.\r
-\r
-<br>\r
-@subpage getting_control_button_events\r
-\r
-Lightpad and Control Blocks have control buttons, either a mode button on their side or labelled buttons on top, and this section shows you how to obtain button pressed and button released events.\r
-\r
-<br>\r
-@subpage controlling_led_grids\r
-\r
-This section explains how to control the LED grid on a Lightpad.\r
-\r
-<br>\r
-@subpage the_littlefoot_language\r
-\r
-Advanced SDK users can specify specialised programs to run on Lightpad Blocks.\r
-These programs must be written in the LittleFoot language, which is described\r
-in this section.\r
-\r
-<br>\r
-@subpage controlling_led_strips\r
-\r
-Control Blocks have a strip of lights running along one side and this section provides instructions for controling the individual LEDs.\r
-\r
-<br>\r
-@subpage controlling_control_buttons\r
-\r
-As well as providing button pressed and button released events, control buttons also have LEDs.\r
-This section explains how to change the colour of different buttons.\r
-\r
-<br>\r
-@subpage the_standalone_blocks_sdk\r
-\r
-The easiest way to get started using the SDK is via the <a href="https://github.com/julianstorer/JUCE">JUCE framework</a>, but if you want to integrate BLOCKS functionality into your existing application then it may be more convenient to use @ref the_standalone_blocks_sdk.\r
-This section gives an overview of building and using the BLOCKS SDK as a library.\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_the_littlefoot_language.dox b/extras/BLOCKS/doxygen/pages/juce_the_littlefoot_language.dox
deleted file mode 100644 (file)
index 82b5a57..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/**\r
-@page the_littlefoot_language The LittleFoot Language\r
-\r
-@section littlefoot_description A description of the LittleFoot language\r
-\r
-A description of the LittleFoot language is contained in the SDK source code at <tt>juce_blocks_basics/littlefoot/LittleFoot Language README.txt</tt>:\r
-@includedoc "LittleFoot Language README.txt"\r
-\r
-@section littlefoot_example A LittleFoot example\r
-\r
-The %BitmapLEDProgram class is a simple example of a LittleFoot program.\r
-\r
-<tt>%juce_blocks_basics/visualisers/juce_BitmapLEDProgram.h</tt>\r
-@include juce_blocks_basics/visualisers/juce_BitmapLEDProgram.h\r
-\r
-<tt>juce_blocks_basics/visualisers/juce_BitmapLEDProgram.cpp</tt>\r
-@include juce_blocks_basics/visualisers/juce_BitmapLEDProgram.cpp\r
-\r
-The repaint() method of the LittleFoot program is called at approximately 25 Hz, and each time it simply inspects the heap (the shared area of memory used to communicate between your application code and your LittleFoot program) and sets the LEDs based on the heap's content.\r
-To update the heap, and hence the LEDS, your application code calls BitmapLEDProgram::setLED.\r
-\r
-A more advanced example can be found in the source code of the DrumPadGridProgram class or in the @ref example_blocks_synth example.\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/pages/juce_the_standalone_blocks_sdk.dox b/extras/BLOCKS/doxygen/pages/juce_the_standalone_blocks_sdk.dox
deleted file mode 100644 (file)
index 9df215e..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/**\r
-@page the_standalone_blocks_sdk The standalone BLOCKS SDK\r
-\r
-The easiest way to get started developing BLOCKS applications is to use <a href="https://github.com/julianstorer/JUCE">the JUCE framework</a>, but if you would prefer not to use JUCE directly the standalone BLOCKS SDK can be obtained from the <a href="https://github.com/WeAreROLI/BLOCKS-SDK">BLOCKS-SDK repository</a>.\r
-\r
-The most straightforward way to use the SDK is to compile the SDK source code into a static library.\r
-Then, in your BLOCKS application code, you can use the header files in the SDK to give you access to the BLOCKS classes and functions.\r
-Finally, when you want to compile your application, you must link against the static library to get all the BLOCKS functionality.\r
-\r
-@section standalone_building_library Building the SDK library\r
-\r
-The source code for the BLOCKS SDK library is contained within the <tt>SDK</tt> directory of the BLOCKS-SDK repository.\r
-Here you will find header files that you can include in your own projects and the <tt>Build</tt> subdirectory contains an Xcode project, a Visual Studio project and a Linux Makefile for compiling the SDK source code into a static library.\r
-Use the appropriate choice for your platform, select either the "Debug" or "Release" configuration, and build the project.\r
-\r
-For MacOS this will produce <tt>libBLOCKS-SDK.a</tt> in either the <tt>SDK/Build/MacOS/Debug/</tt> or <tt>SDK/Build/MacOS/Release/</tt> directory, for Linux this will produce <tt>libBLOCKS-SDK.a</tt> in either the <tt>SDK/Build/Linux/Debug/</tt> or <tt>SDK/Build/Linux/Release/</tt> directory, and for Windows this will produce <tt>BLOCKS-SDK.lib</tt> in either the <tt>SDK\\Build\\Windows\\x64\\Debug</tt> or <tt>SDK\\Build\\Windows\\x64\\Release</tt> folder.\r
-\r
-@section standalone_using_header Using the SDK header file\r
-\r
-To use BLOCKS classes and functions in your application you must include the <tt>BlocksHeader.h</tt> file in your source code.\r
-You also need to tell the compiler to look in the <tt>SDK</tt> directory for additional header files, which you can configure inside your Xcode or Visual Studio project.\r
-If you are using the command line to compile your application then you can see an example of how to do this in <tt>examples/BLOCKS-SDK/BlockFinder/Linux/Makefile</tt> (which is also configured for MacOS, despite being located inside the Linux directory).\r
-\r
-@section standalone_linking Linking against the SDK library\r
-\r
-You must also tell your compiler where to find the SDK static library before your BLOCKS application will compile, and include all of the dependencies for your platform, which are listed in the @ref standalone_dependencies section.\r
-Again, this is configured in your Xcode or Visual Studio project, but if you are using the command line you can see an example of how to do this in <tt>examples/BLOCKS-SDK/BlockFinder/Linux/Makefile</tt> (which, again, is also configured for MacOS).\r
-\r
-@section standalone_example An example application\r
-\r
-The source code for this example can be found in the <a href="https://github.com/WeAreROLI/BLOCKS-SDK">BLOCKS-SDK repository</a> at <tt>examples/BlockFinder/</tt>, with the parts that are specific to different operating systems in the corresonding subdirectories.\r
-\r
-The main functionality of the application is contained within the following class:\r
-\r
-<tt>BlockFinder/BlockFinder.h</tt>:\r
-@include BlockFinder/BlockFinder.h\r
-\r
-<tt>BlockFinder/BlockFinder.cpp</tt>:\r
-@include BlockFinder/BlockFinder.cpp\r
-\r
-All this class does is create a PhysicalTopologySource and register for TopologySource::Listener::topologyChanged() callbacks---for more information about how this works you should see the @ref discovering_blocks section.\r
-When the topology changes we print some information about the available BLOCKS.\r
-\r
-The <tt>main</tt> function of the MacOS application is the easiest to understand.\r
-\r
-<tt>BlockFinder/MacOS/main.mm</tt>:\r
-@include BlockFinder/MacOS/main.mm\r
-\r
-Here we simply perform some JUCE initialisation, instantiate a BlockFinder class, then run the event loop.\r
-Whilst in the event loop, the <tt>finder</tt> object receives TopologySource::Listener::topologyChanged() callbacks and we see output printed to stdout when BLOCKS are connected or disconnected.\r
-\r
-@section standalone_dependencies Standalone SDK dependencies\r
-\r
-- A C++11 compatible compiler\r
-\r
-@subsection standalone_libraries_macos MacOS frameworks\r
-\r
-- Accelerate\r
-- AudioToolbox\r
-- CoreAudio\r
-- CoreMIDI\r
-\r
-@subsection standalone_libraries_linux Linux packages\r
-\r
-- x11\r
-- alsa\r
-- libcurl\r
-*/\r
diff --git a/extras/BLOCKS/doxygen/stylesheet.css b/extras/BLOCKS/doxygen/stylesheet.css
deleted file mode 100644 (file)
index f41da2b..0000000
+++ /dev/null
@@ -1,2178 +0,0 @@
-@font-face {
-    font-family: Contax Pro;
-    src: url("data:application/x-font-woff;charset=utf-8;base64,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") format("woff");
-    font-weight: 400;
-    font-style: normal
-}
-@font-face {
-    font-family: Contax Pro;
-    src: url("data:application/x-font-woff;charset=utf-8;base64,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") format("woff");
-    font-weight: 700;
-    font-style: normal
-}
-p {
-    letter-spacing: .3
-}
-.center,
-.center-text {
-    text-align: center
-}
-h1,
-h2,
-h3,
-h4 {
-    font-weight: 400;
-    letter-spacing: .3
-}
-.heading--bold {
-    font-weight: 900;
-    font-smoothing: antialiased
-}
-hr {
-    border-top: 2px solid #fbfbfb;
-    margin: 20px 0
-}
-.link-list {
-    padding-left: 0
-}
-.link-list>li {
-    text-decoration: none;
-    list-style: none;
-    margin: 20px 0
-}
-.link-list>li a {
-    color: #397fba
-}
-.headed-list {
-    list-style: none;
-    position: relative;
-    padding-left: 0
-}
-.headed-list li {
-    position: relative;
-    margin: 0
-}
-.headed-list li+li {
-    margin-top: 2em
-}
-.headed-list h5 {
-    font-size: 15px;
-    font-weight: 700;
-    margin: 0
-}
-.headed-list p {
-    margin: 0
-}
-.pretty {
-    list-style: none;
-    padding-left: 1em
-}
-.pretty li {
-    position: relative
-}
-.pretty li:before {
-    content: '';
-    position: absolute;
-    display: block;
-    width: .3em;
-    height: .3em;
-    border-radius: 50%;
-    left: -1em;
-    background: #d1d3d3;
-    top: .6em
-}
-.pretty-ol {
-    padding-left: 1em
-}
-.pretty-ol li {
-    padding-left: .5em
-}
-.inline-link,
-p a {
-    text-decoration: underline;
-    color: #4665a2
-}
-a:focus,
-button:active,
-button:focus {
-    outline: none
-}
-.svg-icon {
-    vertical-align: bottom
-}
-.small-print>* {
-    font-size: 12px
-}
-.small-print h2,
-.small-print h3,
-.small-print h4,
-.small-print h5 {
-    font-size: 14px
-}
-.sm {
-    position: relative;
-    z-index: 9999
-}
-.sm,
-.sm li,
-.sm ul {
-    display: block;
-    list-style: none;
-    margin: 0;
-    padding: 0;
-    line-height: normal;
-    direction: ltr;
-    text-align: left;
-    -webkit-tap-highlight-color: transparent
-}
-.sm-rtl,
-.sm-rtl li,
-.sm-rtl ul {
-    direction: rtl;
-    text-align: right
-}
-.sm>li>h1,
-.sm>li>h2,
-.sm>li>h3,
-.sm>li>h4,
-.sm>li>h5,
-.sm>li>h6 {
-    margin: 0;
-    padding: 0
-}
-.sm ul {
-    display: none
-}
-.sm a,
-.sm li {
-    position: relative
-}
-.sm a {
-    display: block
-}
-.sm a.disabled {
-    cursor: not-allowed
-}
-.sm:after {
-    display: block;
-    height: 0;
-    font: 0/0 serif;
-    clear: both;
-    visibility: hidden;
-    overflow: hidden
-}
-.sm,
-.sm *,
-.sm:after,
-.sm:before {
-    box-sizing: border-box
-}
-.sm-dox {
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAIAAADHFsdbAAAAcElEQVR4Ae3dTQ6DIBRF4ce70NS4uA51YOLAtFYw0B+gxn06dAddRMGykHO/5K6Ctv3LdaX4fJJ4+RXuvcA+/xkXMbsPJhugbcQ4B9xT2dF43EzAVfscExGa3rIQxGkORZaK5U9zhKKSGYFueODS6h/TSxpOsn4UagAAAABJRU5ErkJggg==)
-}
-.sm-dox a,
-.sm-dox a:active,
-.sm-dox a:focus,
-.sm-dox a:hover {
-    padding: 0 12px;
-    padding-right: 43px;
-    font-family: Lucida Grande, Geneva, Helvetica, Arial, sans-serif;
-    font-size: 13px;
-    font-weight: 700;
-    line-height: 36px;
-    text-decoration: none;
-    text-shadow: 0 1px 1px hsla(0, 0%, 100%, .9);
-    color: #283a5d;
-    outline: 0
-}
-.sm-dox a:hover {
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAIAAADHFsdbAAAAVUlEQVR4Ae2dSwqAMBBDJ2+kKIqIW8W94CXceP8j2amt5wgJ+Z3B9vOmH1emZSMNM3QJSRkgHDMrkLz4ReN+XA9EHr0fOa/b4OiSd023v/b/fX9Z9V/qQQI0WZ7jfQAAAABJRU5ErkJggg==);
-    background-repeat: repeat-x;
-    color: #fff;
-    text-shadow: 0 1px 1px #000
-}
-.sm-dox a.current {
-    color: #d23600
-}
-.sm-dox a.disabled {
-    color: #bbb
-}
-.sm-dox a span.sub-arrow {
-    position: absolute;
-    top: 50%;
-    margin-top: -14px;
-    left: auto;
-    right: 3px;
-    width: 28px;
-    height: 28px;
-    overflow: hidden;
-    font: 700 12px/28px monospace!important;
-    text-align: center;
-    text-shadow: none;
-    background: hsla(0, 0%, 100%, .5);
-    border-radius: 5px
-}
-.sm-dox a.highlighted span.sub-arrow:before {
-    display: block;
-    content: '-'
-}
-.sm-dox>li:first-child>:not(ul) a,
-.sm-dox>li:first-child>a {
-    border-radius: 5px 5px 0 0
-}
-.sm-dox>li:last-child>:not(ul) a,
-.sm-dox>li:last-child>a,
-.sm-dox>li:last-child>ul,
-.sm-dox>li:last-child>ul>li:last-child>:not(ul) a,
-.sm-dox>li:last-child>ul>li:last-child>a,
-.sm-dox>li:last-child>ul>li:last-child>ul,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>:not(ul) a,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>:not(ul) a,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>:not(ul) a,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul {
-    border-radius: 0 0 5px 5px
-}
-.sm-dox>li:last-child>:not(ul) a.highlighted,
-.sm-dox>li:last-child>a.highlighted,
-.sm-dox>li:last-child>ul>li:last-child>:not(ul) a.highlighted,
-.sm-dox>li:last-child>ul>li:last-child>a.highlighted,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>:not(ul) a.highlighted,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>:not(ul) a.highlighted,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>:not(ul) a.highlighted,
-.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted {
-    border-radius: 0
-}
-.sm-dox ul {
-    background: hsla(0, 0%, 64%, .1)
-}
-.sm-dox ul a,
-.sm-dox ul a:active,
-.sm-dox ul a:focus,
-.sm-dox ul a:hover {
-    font-size: 12px;
-    border-left: 8px solid transparent;
-    line-height: 36px;
-    text-shadow: none;
-    background-color: #fff;
-    background-image: none
-}
-.sm-dox ul a:hover {
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAIAAADHFsdbAAAAVUlEQVR4Ae2dSwqAMBBDJ2+kKIqIW8W94CXceP8j2amt5wgJ+Z3B9vOmH1emZSMNM3QJSRkgHDMrkLz4ReN+XA9EHr0fOa/b4OiSd023v/b/fX9Z9V/qQQI0WZ7jfQAAAABJRU5ErkJggg==);
-    background-repeat: repeat-x;
-    color: #fff;
-    text-shadow: 0 1px 1px #000
-}
-.sm-dox ul ul a,
-.sm-dox ul ul a:active,
-.sm-dox ul ul a:focus,
-.sm-dox ul ul a:hover {
-    border-left: 16px solid transparent
-}
-.sm-dox ul ul ul a,
-.sm-dox ul ul ul a:active,
-.sm-dox ul ul ul a:focus,
-.sm-dox ul ul ul a:hover {
-    border-left: 24px solid transparent
-}
-.sm-dox ul ul ul ul a,
-.sm-dox ul ul ul ul a:active,
-.sm-dox ul ul ul ul a:focus,
-.sm-dox ul ul ul ul a:hover {
-    border-left: 32px solid transparent
-}
-.sm-dox ul ul ul ul ul a,
-.sm-dox ul ul ul ul ul a:active,
-.sm-dox ul ul ul ul ul a:focus,
-.sm-dox ul ul ul ul ul a:hover {
-    border-left: 40px solid transparent
-}
-@mediamin-width768px {
-    .sm-dox ul {
-        position: absolute;
-        width: 12em
-    }
-    .sm-dox li {
-        float: left
-    }
-    .sm-dox.sm-rtl li {
-        float: right
-    }
-    .sm-dox.sm-rtl ul li,
-    .sm-dox.sm-vertical li,
-    .sm-dox ul li {
-        float: none
-    }
-    .sm-dox a {
-        white-space: nowrap
-    }
-    .sm-dox.sm-vertical a,
-    .sm-dox ul a {
-        white-space: normal
-    }
-    .sm-dox .sm-nowrap>li>:not(ul) a,
-    .sm-dox .sm-nowrap>li>a {
-        white-space: nowrap
-    }
-    .sm-dox {
-        padding: 0 10px;
-        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAIAAADHFsdbAAAAcElEQVR4Ae3dTQ6DIBRF4ce70NS4uA51YOLAtFYw0B+gxn06dAddRMGykHO/5K6Ctv3LdaX4fJJ4+RXuvcA+/xkXMbsPJhugbcQ4B9xT2dF43EzAVfscExGa3rIQxGkORZaK5U9zhKKSGYFueODS6h/TSxpOsn4UagAAAABJRU5ErkJggg==);
-        line-height: 36px
-    }
-    .sm-dox a span.sub-arrow {
-        top: 50%;
-        margin-top: -2px;
-        right: 12px;
-        width: 0;
-        height: 0;
-        border-width: 4px;
-        border-style: solid dashed dashed;
-        border-color: #283a5d transparent transparent;
-        background: transparent;
-        border-radius: 0
-    }
-    .sm-dox a,
-    .sm-dox a.highlighted,
-    .sm-dox a:active,
-    .sm-dox a:focus,
-    .sm-dox a:hover {
-        padding: 0 12px;
-        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAIAAADHFsdbAAAAf0lEQVR4Ae3dgQmCQABA0aM/URIUhaQimqIlpkmRl4pmljZbG7RIw+RRgzzeGuL1/pBdnmRyIM1/knM/GohPPdHx8XcnzEaHjiDt8PYtfnLDjVuc6Iqt7BqsbYMZ1qyDGt2v0L2K1UYpWbolC6dgbhfMLDkRQqCZkqkh0Yxc/QU8xSP87u6VHwAAAABJRU5ErkJggg==);
-        background-repeat: no-repeat;
-        background-position: 100%;
-        border-radius: 0!important
-    }
-    .sm-dox a:hover {
-        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAIAAADHFsdbAAAAVUlEQVR4Ae2dSwqAMBBDJ2+kKIqIW8W94CXceP8j2amt5wgJ+Z3B9vOmH1emZSMNM3QJSRkgHDMrkLz4ReN+XA9EHr0fOa/b4OiSd023v/b/fX9Z9V/qQQI0WZ7jfQAAAABJRU5ErkJggg==);
-        background-repeat: repeat-x;
-        color: #fff;
-        text-shadow: 0 1px 1px #000
-    }
-    .sm-dox a:hover span.sub-arrow {
-        border-color: #fff transparent transparent
-    }
-    .sm-dox a.has-submenu {
-        padding-right: 24px
-    }
-    .sm-dox li {
-        border-top: 0
-    }
-    .sm-dox>li>ul:after,
-    .sm-dox>li>ul:before {
-        content: '';
-        position: absolute;
-        top: -18px;
-        left: 30px;
-        width: 0;
-        height: 0;
-        overflow: hidden;
-        border-width: 9px;
-        border-style: dashed dashed solid;
-        border-color: transparent transparent #bbb
-    }
-    .sm-dox>li>ul:after {
-        top: -16px;
-        left: 31px;
-        border-width: 8px;
-        border-color: transparent transparent #fff
-    }
-    .sm-dox ul {
-        border: 1px solid #bbb;
-        padding: 5px 0;
-        background: #fff;
-        border-radius: 5px!important;
-        box-shadow: 0 5px 9px rgba(0, 0, 0, .2)
-    }
-    .sm-dox ul a span.sub-arrow {
-        right: 8px;
-        top: 50%;
-        margin-top: -5px;
-        border-width: 5px;
-        border-color: transparent transparent transparent #555;
-        border-style: dashed dashed dashed solid
-    }
-    .sm-dox ul a,
-    .sm-dox ul a.highlighted,
-    .sm-dox ul a:active,
-    .sm-dox ul a:focus,
-    .sm-dox ul a:hover {
-        border: 0!important;
-        color: #555;
-        background-image: none
-    }
-    .sm-dox ul a:hover {
-        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAIAAADHFsdbAAAAVUlEQVR4Ae2dSwqAMBBDJ2+kKIqIW8W94CXceP8j2amt5wgJ+Z3B9vOmH1emZSMNM3QJSRkgHDMrkLz4ReN+XA9EHr0fOa/b4OiSd023v/b/fX9Z9V/qQQI0WZ7jfQAAAABJRU5ErkJggg==);
-        background-repeat: repeat-x;
-        color: #fff;
-        text-shadow: 0 1px 1px #000
-    }
-    .sm-dox ul a:hover span.sub-arrow {
-        border-color: transparent transparent transparent #fff
-    }
-    .sm-dox span.scroll-down,
-    .sm-dox span.scroll-up {
-        position: absolute;
-        display: none;
-        visibility: hidden;
-        overflow: hidden;
-        background: #fff;
-        height: 36px
-    }
-    .sm-dox span.scroll-down:hover,
-    .sm-dox span.scroll-up:hover {
-        background: #eee
-    }
-    .sm-dox span.scroll-up:hover span.scroll-down-arrow,
-    .sm-dox span.scroll-up:hover span.scroll-up-arrow {
-        border-color: transparent transparent #d23600
-    }
-    .sm-dox span.scroll-down:hover span.scroll-down-arrow {
-        border-color: #d23600 transparent transparent
-    }
-    .sm-dox span.scroll-down-arrow,
-    .sm-dox span.scroll-up-arrow {
-        position: absolute;
-        top: 0;
-        left: 50%;
-        margin-left: -6px;
-        width: 0;
-        height: 0;
-        overflow: hidden;
-        border-width: 6px;
-        border-style: dashed dashed solid;
-        border-color: transparent transparent #555
-    }
-    .sm-dox span.scroll-down-arrow {
-        top: 8px;
-        border-style: solid dashed dashed;
-        border-color: #555 transparent transparent
-    }
-    .sm-dox.sm-rtl a.has-submenu {
-        padding-right: 12px;
-        padding-left: 24px
-    }
-    .sm-dox.sm-rtl a span.sub-arrow {
-        right: auto;
-        left: 12px
-    }
-    .sm-dox.sm-rtl.sm-vertical a.has-submenu {
-        padding: 10px 20px
-    }
-    .sm-dox.sm-rtl.sm-vertical a span.sub-arrow {
-        right: auto;
-        left: 8px;
-        border-style: dashed solid dashed dashed;
-        border-color: transparent #555 transparent transparent
-    }
-    .sm-dox.sm-rtl>li>ul:before {
-        left: auto;
-        right: 30px
-    }
-    .sm-dox.sm-rtl>li>ul:after {
-        left: auto;
-        right: 31px
-    }
-    .sm-dox.sm-rtl ul a.has-submenu {
-        padding: 10px 20px!important
-    }
-    .sm-dox.sm-rtl ul a span.sub-arrow {
-        right: auto;
-        left: 8px;
-        border-style: dashed solid dashed dashed;
-        border-color: transparent #555 transparent transparent
-    }
-    .sm-dox.sm-vertical {
-        padding: 10px 0;
-        border-radius: 5px
-    }
-    .sm-dox.sm-vertical a {
-        padding: 10px 20px
-    }
-    .sm-dox.sm-vertical a.highlighted,
-    .sm-dox.sm-vertical a:active,
-    .sm-dox.sm-vertical a:focus,
-    .sm-dox.sm-vertical a:hover {
-        background: #fff
-    }
-    .sm-dox.sm-vertical a.disabled {
-        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAIAAADHFsdbAAAAcElEQVR4Ae3dTQ6DIBRF4ce70NS4uA51YOLAtFYw0B+gxn06dAddRMGykHO/5K6Ctv3LdaX4fJJ4+RXuvcA+/xkXMbsPJhugbcQ4B9xT2dF43EzAVfscExGa3rIQxGkORZaK5U9zhKKSGYFueODS6h/TSxpOsn4UagAAAABJRU5ErkJggg==)
-    }
-    .sm-dox.sm-vertical a span.sub-arrow {
-        right: 8px;
-        top: 50%;
-        margin-top: -5px;
-        border-width: 5px;
-        border-style: dashed dashed dashed solid;
-        border-color: transparent transparent transparent #555
-    }
-    .sm-dox.sm-vertical>li>ul:after,
-    .sm-dox.sm-vertical>li>ul:before {
-        display: none
-    }
-    .sm-dox.sm-vertical ul a {
-        padding: 10px 20px
-    }
-    .sm-dox.sm-vertical ul a.highlighted,
-    .sm-dox.sm-vertical ul a:active,
-    .sm-dox.sm-vertical ul a:focus,
-    .sm-dox.sm-vertical ul a:hover {
-        background: #eee
-    }
-    .sm-dox.sm-vertical ul a.disabled {
-        background: #fff
-    }
-}
-#nav-tree .children_ul {
-    margin: 0;
-    padding: 4px
-}
-#nav-tree ul {
-    list-style: none outside none;
-    margin: 0;
-    padding: 0
-}
-#nav-tree li {
-    white-space: nowrap;
-    margin: 0;
-    padding: 0
-}
-#nav-tree .plus {
-    margin: 0
-}
-#nav-tree img {
-    margin: 0;
-    padding: 0;
-    border: 0;
-    vertical-align: middle
-}
-#nav-tree a {
-    text-decoration: none;
-    padding: 0;
-    margin: 0;
-    outline: none
-}
-#nav-tree .label {
-    margin: 0;
-    padding: 0;
-    font: 16px "Contax Pro", Lucida Grande, Geneva, Helvetica, Arial, sans-serif;
-    line-height: 160%
-}
-#nav-tree .label a {
-    padding: 2px
-}
-#nav-tree .children_ul,
-#nav-tree .item {
-    margin: 0;
-    padding: 0
-}
-#nav-tree {
-    font-size: 14px
-}
-#doc-content,
-#nav-tree {
-    padding: 0;
-    overflow: auto
-}
-#doc-content {
-    display: block;
-    margin: 0;
-    -webkit-overflow-scrolling: touch
-}
-#side-nav {
-    padding: 0 6px 0 0;
-    margin: 0;
-    position: absolute;
-    left: 0;
-    width: 320px
-}
-#side-nav,
-.ui-resizable .ui-resizable-handle {
-    display: block;
-}
-.ui-resizable-e {
-    cursor: ew-resize;
-    height: 100%;
-    right: 0;
-    top: 0;
-    width: 6px
-}
-.ui-resizable-handle {
-    display: none;
-    font-size: .1px;
-    position: absolute;
-    z-index: 1
-}
-#nav-tree-contents {
-    margin: 6px 0 0
-}
-#nav-tree {
-    -webkit-overflow-scrolling: touch
-}
-#nav-sync {
-    position: absolute;
-    top: 5px;
-    right: 24px;
-    z-index: 0;
-    display: none;
-}
-#nav-sync img {
-    opacity: .3
-}
-#nav-sync img:hover {
-    opacity: .9
-}
-@media print {
-    #nav-tree {
-        display: none
-    }
-    div.ui-resizable-handle {
-        display: none;
-        position: relative
-    }
-}
-#FSearchBox {
-    float: left
-}
-#MSearchBox {
-    white-space: nowrap;
-    float: none;
-    margin-top: 0;
-    right: 0;
-    width: 170px;
-    height: 24px;
-    z-index: 102;
-    display: none;
-    position: absolute
-}
-#MSearchSelect {
-    display: block;
-    position: absolute;
-    width: 20px;
-    height: 19px
-}
-.left #MSearchSelect {
-    left: 4px
-}
-.right #MSearchSelect {
-    right: 5px
-}
-#MSearchField {
-    border: none;
-    width: 111px;
-    margin-left: 20px;
-    outline: none;
-    -webkit-border-radius: 0
-}
-#FSearchBox #MSearchField {
-    margin-left: 15px
-}
-#MSearchClose {
-    display: none;
-    position: absolute;
-    top: 4px;
-    background: none;
-    border: none;
-    margin: 0 4px 0 0;
-    padding: 0;
-    outline: none
-}
-.left #MSearchClose {
-    left: 6px
-}
-.right #MSearchClose {
-    right: 2px
-}
-.MSearchBoxActive #MSearchField {
-    color: #000
-}
-#MSearchSelectWindow {
-    display: none;
-    position: absolute;
-    left: 0;
-    top: 0;
-    background-color: #f9fafc;
-    z-index: 10001;
-    padding-top: 4px;
-    padding-bottom: 4px;
-    -moz-border-radius: 4px;
-    -webkit-border-top-left-radius: 4px;
-    -webkit-border-top-right-radius: 4px;
-    -webkit-border-bottom-left-radius: 4px;
-    -webkit-border-bottom-right-radius: 4px;
-    -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, .15)
-}
-.SelectItem {
-    font: 8pt Arial, Verdana, sans-serif;
-    padding-left: 2px;
-    padding-right: 12px;
-    border: 0
-}
-span.SelectionMark {
-    margin-right: 4px;
-    font-family: monospace;
-    outline-style: none;
-    text-decoration: none
-}
-a.SelectItem {
-    display: block;
-    padding-left: 6px;
-    padding-right: 12px
-}
-a.SelectItem,
-a.SelectItem:active,
-a.SelectItem:focus {
-    outline-style: none;
-    color: #000;
-    text-decoration: none
-}
-a.SelectItem:hover {
-    color: #fff;
-    outline-style: none;
-    text-decoration: none;
-    cursor: pointer;
-    display: block
-}
-iframe#MSearchResults {
-    width: 60ex;
-    height: 15em
-}
-#MSearchResultsWindow {
-    display: none;
-    position: absolute;
-    left: 0;
-    top: 0;
-    border: 1px solid #000;
-    z-index: 10000
-}
-#SRIndex {
-    clear: both;
-    padding-bottom: 15px
-}
-.SREntry {
-    font: 400 10px/16px "Contax Pro", sans-serif;
-    font-size: 14pt;
-    padding-left: 1ex
-}
-.SRPage .SREntry {
-    font-size: 10pt;
-    padding: 1px 5px
-}
-body.SRPage {
-    margin: 5px 2px
-}
-.SRChildren {
-    padding-left: 3ex;
-    padding-bottom: .5em
-}
-.SRPage .SRChildren {
-    display: none
-}
-.SRSymbol {
-    font-weight: 700
-}
-.SRSymbol,
-a.SRScope {
-    color: #425e97;
-    font-family: Arial, Verdana, sans-serif;
-    text-decoration: none;
-    outline: none
-}
-a.SRScope {
-    display: block
-}
-a.SRScope:active,
-a.SRScope:focus,
-a.SRSymbol:active,
-a.SRSymbol:focus {
-    text-decoration: underline
-}
-span.SRScope {
-    padding-left: 4px
-}
-.SRPage .SRStatus {
-    padding: 2px 5px;
-    font-size: 8pt;
-    font-style: italic
-}
-.SRResult {
-    display: none
-}
-DIV.searchresults {
-    margin-left: 10px;
-    margin-right: 10px
-}
-.searchresult {
-    background-color: #f0f3f8
-}
-.pages b {
-    color: #fff;
-    padding: 5px 5px 3px;
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAIAAADHFsdbAAAAVUlEQVR4Ae2dSwqAMBBDJ2+kKIqIW8W94CXceP8j2amt5wgJ+Z3B9vOmH1emZSMNM3QJSRkgHDMrkLz4ReN+XA9EHr0fOa/b4OiSd023v/b/fX9Z9V/qQQI0WZ7jfQAAAABJRU5ErkJggg==);
-    background-repeat: repeat-x;
-    text-shadow: 0 1px 1px #000
-}
-.pages {
-    line-height: 17px;
-    margin-left: 4px;
-    text-decoration: none
-}
-.hl {
-    font-weight: 700
-}
-#searchresults {
-    margin-bottom: 20px
-}
-.searchpages {
-    margin-top: 10px
-}
-body,
-div,
-dl,
-p,
-table {
-    font: 400 16px/24px "Contax Pro", sans-serif;
-}
-h1.groupheader {
-    font-size: 150%
-}
-.title {
-    font: 400 16px/32px "Contax Pro", sans-serif;
-    font-weight: 700;
-    font-size: 32px;
-    margin: 10px 2px
-}
-h2.groupheader {
-    font-size: 150%;
-    font-weight: 400;
-    margin-top: 1.75em;
-    padding-top: 8px;
-    padding-bottom: 4px;
-    width: 100%
-}
-h3.groupheader {
-    font-size: 100%
-}
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
-    -webkit-transition: text-shadow .5s linear;
-    transition: text-shadow .5s linear;
-    margin-right: 15px
-}
-h1.glow,
-h2.glow,
-h3.glow,
-h4.glow,
-h5.glow,
-h6.glow {
-    text-shadow: 0 0 15px cyan
-}
-dt {
-    font-weight: 700
-}
-div.multicol {
-    -moz-column-gap: 1em;
-    -webkit-column-gap: 1em;
-    -moz-column-count: 3;
-    -webkit-column-count: 3
-}
-p.startdd,
-p.startli {
-    margin-top: 2px
-}
-p.starttd {
-    margin-top: 0
-}
-p.endli {
-    margin-bottom: 0
-}
-p.enddd {
-    margin-bottom: 4px
-}
-p.endtd {
-    margin-bottom: 2px
-}
-caption {
-    font-weight: 700
-}
-span.legend {
-    font-size: 70%;
-    text-align: center
-}
-h3.version {
-    font-size: 90%;
-    text-align: center
-}
-div.navtab,
-div.qindex {
-    background-color: #ebeff6;
-    border: 1px solid #a3b4d7;
-    text-align: center
-}
-div.navpath,
-div.qindex {
-    width: 100%;
-    line-height: 140%
-}
-div.navtab {
-    margin-right: 15px
-}
-.contents a:visited {
-    color: #121c2f
-}
-a:hover {
-    text-decoration: underline
-}
-a.qindex,
-a.qindexHL {
-    font-weight: 700
-}
-a.qindexHL {
-    background-color: #9cafd4;
-    color: #fff;
-    border: 1px double #869dca
-}
-.contents a.qindexHL:visited {
-    color: #fff
-}
-a.el {
-    font-weight: 700
-}
-a.code,
-a.code:visited,
-a.codeRef,
-a.codeRef:visited,
-a.line,
-a.line:visited,
-a.lineRef,
-a.lineRef:visited {
-    color: #121c2f
-}
-dl.el {
-    margin-left: -1cm
-}
-pre.fragment {
-    padding: 4px 6px;
-    overflow: auto;
-    word-wrap: break-word;
-    font-size: 9pt;
-    line-height: 125%;
-    font-family: monospace, fixed;
-    font-size: 105%
-}
-div.fragment,
-pre.fragment {
-    border: 1px solid #c4cfe5;
-    background-color: #fbfcfd;
-    margin: 4px 8px 4px 2px
-}
-div.fragment {
-    padding: 0
-}
-div.line {
-    font-family: monospace, fixed;
-    font-size: 13px;
-    min-height: 13px;
-    line-height: 1;
-    text-wrap: unrestricted;
-    white-space: -moz-pre-wrap;
-    white-space: -pre-wrap;
-    white-space: -o-pre-wrap;
-    white-space: pre-wrap;
-    word-wrap: break-word;
-    text-indent: -53px;
-    padding-left: 53px;
-    padding-bottom: 0;
-    margin: 0;
-    -webkit-transition-property: background-color, box-shadow;
-    -webkit-transition-duration: .5s;
-    -moz-transition-property: background-color, box-shadow;
-    -moz-transition-duration: .5s;
-    -ms-transition-property: background-color, box-shadow;
-    -ms-transition-duration: .5s;
-    -o-transition-property: background-color, box-shadow;
-    -o-transition-duration: .5s;
-    transition-property: background-color, box-shadow;
-    transition-duration: .5s
-}
-div.line:after {
-    white-space: pre
-}
-div.line.glow {
-    background-color: cyan;
-    box-shadow: 0 0 10px cyan
-}
-span.lineno {
-    padding-right: 4px;
-    text-align: right;
-    border-right: 2px solid #0f0;
-    background-color: #e8e8e8;
-    white-space: pre
-}
-span.lineno a {
-    background-color: #d8d8d8
-}
-span.lineno a:hover {
-    background-color: #c8c8c8
-}
-.lineno {
-    -webkit-touch-callout: none;
-    -webkit-user-select: none;
-    -moz-user-select: none;
-    -ms-user-select: none;
-    user-select: none
-}
-div.ah,
-span.ah {
-    background-color: #000;
-    font-weight: 700;
-    color: #fff;
-    margin-bottom: 3px;
-    margin-top: 3px;
-    padding: .2em;
-    border: thin solid #333;
-    border-radius: .5em;
-    -webkit-border-radius: .5em;
-    -moz-border-radius: .5em;
-    box-shadow: 2px 2px 3px #999;
-    -webkit-box-shadow: 2px 2px 3px #999;
-    -moz-box-shadow: rgba(0, 0, 0, .15) 2px 2px 2px;
-    background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000), color-stop(.3, #444));
-    background-image: -moz-linear-gradient(center top, #eee 0, #444 40%, #000 110%)
-}
-div.classindex ul {
-    list-style: none;
-    padding-left: 0
-}
-div.classindex span.ai {
-    display: inline-block
-}
-div.groupHeader {
-    margin-left: 16px;
-    margin-top: 12px;
-    font-weight: 700
-}
-div.groupText {
-    margin-left: 16px;
-    font-style: italic
-}
-body {
-    background-color: #fff;
-    color: #000;
-    margin: 0
-}
-div.contents {
-    margin-top: 10px;
-    margin-left: 12px;
-    margin-right: 8px
-}
-td.indexkey {
-    font-weight: 700;
-    white-space: nowrap;
-    vertical-align: top
-}
-td.indexkey,
-td.indexvalue {
-    background-color: #ebeff6;
-    border: 1px solid #c4cfe5;
-    margin: 2px 0;
-    padding: 2px 10px
-}
-tr.memlist {
-    background-color: #eef1f7
-}
-p.formulaDsp {
-    text-align: center
-}
-img.formulaInl {
-    vertical-align: middle
-}
-div.center {
-    text-align: center;
-    margin-top: 0;
-    margin-bottom: 0;
-    padding: 0
-}
-div.center img {
-    border: 0
-}
-address.footer {
-    text-align: right;
-    padding-right: 12px
-}
-img.footer {
-    border: 0;
-    vertical-align: middle
-}
-span.keyword {
-    color: green
-}
-span.keywordtype {
-    color: #604020
-}
-span.keywordflow {
-    color: #e08000
-}
-span.comment {
-    color: maroon
-}
-span.preprocessor {
-    color: #806020
-}
-span.stringliteral {
-    color: #002080
-}
-span.charliteral {
-    color: teal
-}
-span.vhdldigit {
-    color: #f0f
-}
-span.vhdlchar {
-    color: #000
-}
-span.vhdlkeyword {
-    color: #700070
-}
-span.vhdllogic {
-    color: red
-}
-blockquote {
-    background-color: #f7f8fb;
-    border-left: 2px solid #9cafd4;
-    margin: 0 24px 0 4px;
-    padding: 0 12px 0 16px
-}
-td.tiny {
-    font-size: 75%
-}
-.dirtab {
-    padding: 4px;
-    border-collapse: collapse;
-    border: 1px solid #a3b4d7
-}
-th.dirtab {
-    background: #ebeff6;
-    font-weight: 700
-}
-hr {
-    height: 0;
-    border: none
-}
-hr.footer {
-    height: 1px
-}
-table.memberdecls {
-    border-spacing: 0;
-    padding: 0
-}
-.fieldtable tr,
-.memberdecls td {
-    -webkit-transition-property: background-color, box-shadow;
-    -webkit-transition-duration: .5s;
-    -moz-transition-property: background-color, box-shadow;
-    -moz-transition-duration: .5s;
-    -ms-transition-property: background-color, box-shadow;
-    -ms-transition-duration: .5s;
-    -o-transition-property: background-color, box-shadow;
-    -o-transition-duration: .5s;
-    transition-property: background-color, box-shadow;
-    transition-duration: .5s
-}
-.fieldtable tr.glow,
-.memberdecls td.glow {
-    background-color: cyan;
-    box-shadow: 0 0 15px cyan
-}
-.mdescLeft,
-.mdescRight,
-.memItemLeft,
-.memItemRight,
-.memTemplItemLeft,
-.memTemplItemRight,
-.memTemplParams {
-    border: none;
-    margin: 4px;
-    padding: 1px 0 0 8px
-}
-.mdescLeft,
-.mdescRight {
-    padding: 0 8px 4px;
-    color: #555
-}
-.memSeparator {
-    border-bottom: 1px solid #dee4f0;
-    line-height: 1px;
-    margin: 0;
-    padding: 0
-}
-.memItemLeft,
-.memTemplItemLeft {
-    white-space: nowrap
-}
-.memItemRight {
-    width: 100%
-}
-.memTemplParams {
-    color: #4665a2;
-    white-space: nowrap;
-    font-size: 80%
-}
-.memtitle {
-    padding: 8px;
-    border-top: 1px solid #a8b8d9;
-    border-left: 1px solid #a8b8d9;
-    border-right: 1px solid #a8b8d9;
-    border-top-right-radius: 4px;
-    border-top-left-radius: 4px;
-    margin-bottom: -1px;
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA4CAIAAACzAgW7AAAAYElEQVR4Ae3dSw6AIAxF0Za3WweG+IFC0W1r4sTCSBwYl3By07wugo7zguqOpBtSNlogVkkFsRJFkII1arOEbBTzmptpSZis3urnSjCM0RHRL477m5kdEXX48fPevzZzA0gYIN0BAPV5AAAAAElFTkSuQmCC);
-    background-repeat: repeat-x;
-    background-color: #e2e8f2;
-    line-height: 1.25;
-    font-weight: 300;
-    float: left
-}
-.permalink {
-    font-size: 65%;
-    display: inline-block;
-    vertical-align: middle
-}
-.memtemplate {
-    font-size: 80%;
-    color: #4665a2;
-    font-weight: 400;
-    margin-left: 9px
-}
-.memnav {
-    background-color: #ebeff6;
-    border: 1px solid #a3b4d7;
-    text-align: center;
-    margin: 2px;
-    margin-right: 15px;
-    padding: 2px
-}
-.memitem,
-.mempage {
-    width: 100%
-}
-.memitem {
-    padding: 0;
-    margin-bottom: 10px;
-    margin-right: 5px;
-    -webkit-transition: box-shadow .5s linear;
-    transition: box-shadow .5s linear;
-    display: table!important
-}
-.memitem.glow {
-    box-shadow: 0 0 15px cyan
-}
-.memname {
-    font-weight: 400;
-    margin-left: 6px
-}
-.memname td {
-    vertical-align: bottom
-}
-.memproto,
-dl.reflist dt {
-    border-top: 1px solid #a8b8d9;
-    border-left: 1px solid #a8b8d9;
-    border-right: 1px solid #a8b8d9;
-    padding: 6px 0;
-    color: #253555;
-    font-weight: 700;
-    text-shadow: 0 1px 1px hsla(0, 0%, 100%, .9);
-    background-color: #dfe5f1;
-    box-shadow: 5px 5px 5px rgba(0, 0, 0, .15);
-    border-top-right-radius: 4px;
-    -moz-box-shadow: rgba(0, 0, 0, .15) 5px 5px 5px;
-    -moz-border-radius-topright: 4px;
-    -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, .15);
-    -webkit-border-top-right-radius: 4px
-}
-.overload {
-    font-family: courier new, courier, monospace;
-    font-size: 65%
-}
-.memdoc,
-dl.reflist dd {
-    border-bottom: 1px solid #a8b8d9;
-    border-left: 1px solid #a8b8d9;
-    border-right: 1px solid #a8b8d9;
-    padding: 6px 10px 2px;
-    background-color: #fbfcfd;
-    border-top-width: 0;
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAGCAYAAAACEPQxAAAAJklEQVR4Ae3dMQ0AAAgDwU9IF2aE4V8NLT5+uOVNIGnLTejAgwcHD1MAvfyCPAUAAAAASUVORK5CYII=);
-    background-repeat: repeat-x;
-    background-color: #fff;
-    border-bottom-left-radius: 4px;
-    border-bottom-right-radius: 4px;
-    box-shadow: 5px 5px 5px rgba(0, 0, 0, .15);
-    -moz-border-radius-bottomleft: 4px;
-    -moz-border-radius-bottomright: 4px;
-    -moz-box-shadow: rgba(0, 0, 0, .15) 5px 5px 5px;
-    -webkit-border-bottom-left-radius: 4px;
-    -webkit-border-bottom-right-radius: 4px;
-    -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, .15)
-}
-dl.reflist dt {
-    padding: 5px
-}
-dl.reflist dd {
-    margin: 0 0 10px;
-    padding: 5px
-}
-.paramkey {
-    text-align: right
-}
-.paramname,
-.paramtype {
-    white-space: nowrap
-}
-.paramname {
-    color: #602020
-}
-.paramname em {
-    font-style: normal
-}
-.paramname code {
-    line-height: 14px
-}
-.exception,
-.params,
-.retval,
-.tparams {
-    margin-left: 0;
-    padding-left: 0
-}
-.params .paramname,
-.retval .paramname {
-    font-weight: 700;
-    vertical-align: top
-}
-.params .paramtype {
-    font-style: italic;
-    vertical-align: top
-}
-.params .paramdir {
-    font-family: courier new, courier, monospace;
-    vertical-align: top
-}
-table.mlabels {
-    border-spacing: 0
-}
-td.mlabels-left {
-    width: 100%;
-    padding: 0
-}
-td.mlabels-right {
-    vertical-align: bottom;
-    padding: 0;
-    white-space: nowrap
-}
-span.mlabels {
-    margin-left: 8px
-}
-span.mlabel {
-    background-color: #728dc1;
-    border-top: 1px solid #5373b4;
-    border-left: 1px solid #5373b4;
-    border-right: 1px solid #c4cfe5;
-    border-bottom: 1px solid #c4cfe5;
-    text-shadow: none;
-    color: #fff;
-    margin-right: 4px;
-    padding: 2px 3px;
-    border-radius: 3px;
-    font-size: 7pt;
-    white-space: nowrap;
-    vertical-align: middle
-}
-div.directory {
-    margin: 10px 0;
-    border-top: 1px solid #9cafd4;
-    border-bottom: 1px solid #9cafd4;
-    width: 100%
-}
-.directory table {
-    border-collapse: collapse
-}
-.directory td {
-    margin: 0;
-    padding: 0;
-    vertical-align: top
-}
-.directory td.entry {
-    white-space: nowrap;
-    padding-right: 6px;
-    padding-top: 3px
-}
-.directory td.entry a {
-    outline: none
-}
-.directory td.entry a img {
-    border: none
-}
-.directory td.desc {
-    width: 100%;
-    padding-left: 6px;
-    padding-right: 6px;
-    padding-top: 3px;
-    border-left: 1px solid rgba(0, 0, 0, .05)
-}
-.directory tr.even {
-    padding-left: 6px;
-    background-color: #f7f8fb
-}
-.directory img {
-    vertical-align: -30%
-}
-.directory .levels {
-    white-space: nowrap;
-    width: 100%;
-    text-align: right;
-    font-size: 9pt
-}
-.directory .levels span {
-    cursor: pointer;
-    padding-left: 2px;
-    padding-right: 2px;
-    color: #3d578c
-}
-.arrow {
-    color: #9cafd4;
-    -webkit-user-select: none;
-    -moz-user-select: none;
-    -ms-user-select: none;
-    user-select: none;
-    cursor: pointer;
-    font-size: 80%;
-    height: 22px
-}
-.arrow,
-.icon {
-    display: inline-block;
-    width: 16px
-}
-.icon {
-    font-family: Arial, Helvetica;
-    font-weight: 700;
-    font-size: 12px;
-    height: 14px;
-    background-color: #728dc1;
-    color: #fff;
-    text-align: center;
-    border-radius: 4px;
-    margin-left: 2px;
-    margin-right: 2px
-}
-.icona {
-    width: 24px;
-    height: 22px;
-    display: inline-block
-}
-.iconfopen {
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAWCAYAAADafVyIAAACHElEQVR4Ae1dP2/TUBD/OWmaNGmwHTuNEGlpk7aJWooAiZGBiQ/AwDdgYujU2ayd2PkOLEjsVSf0JBaQKoFUtV2CVKFEHlDaxDZ3z32JHTuhQzsgYb/Tnd+f+93v7p68akEQAMCtSQYAblP+fYA5AEiT044bfD/twfcDDD1fysaKga2GpQHAdWUqADuvWUXkc1nk5kKin7/+xJejc9kVAb0avdmMhgzJqxebqcBZx3EAICFHx78cdsyHudHYrpoLsIyC1Ea5AH1xHqViDl33Ag837bcAMCnaZJu+//At6Lp9UGbko9ZZezSZ0cJAffrm9PEy2/zUlxbx+uVOjEmCwceDY+fBuiWjrFWKsEmzbRtjsfQFmOW81Mad/Mg+6bh4/nQ5xiS1Bv0LT+ZWRSr1VbTMgucUI57XiJXv+3IdQGwkAPhQ/3JIAGFhGccbpQmym2RarnLokeNxAEmEBABvvBz4VFyOLHSqahAyCB1GQXgfB3YtBkyfGXDXjB1wClTESS8KXKVzZhftvTsMalZpVIPo+qRvXmNwxfy8+xv7u89iXZTCgKKkPA+GYf7VnLKT39MDmHmTow6nOY86jO75K8CPsx6A8eAsRQueZrM26U4AiI3ERaNLVX3cXhI7G7bYblqidd8UrVVTNJcN0azrYu2eTrYu2mum2GpUxPa6JR61quIJnWmvVsTK3fKnmQzI+RsAuCn5/0cDgJnyB7pKCEBUoHiUAAAAAElFTkSuQmCC)
-}
-.iconfclosed,
-.iconfopen {
-    width: 24px;
-    height: 18px;
-    margin-bottom: 4px;
-    background-position: 0 -4px;
-    background-repeat: repeat-y;
-    vertical-align: top;
-    display: inline-block
-}
-.iconfclosed {
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAWCAYAAADafVyIAAACL0lEQVR4Ae1dTU/UQBh+2vp12JBscF32A78jm8VdUFmQRUOIXDn5A7x50d9g1sT/4IH/wMl48+IBokMgJhA9cdDEEI0HowGXdlrnnXa2M22BkNiDh3aeTPtO533e933enb1aQRAAQG6wASBP5E5wCgCSePP+S7Dx8RuAeNxqlLA4c9ECgJMgk4Ccj18bHrxbwu3mp+9EAAAngpUUeXllK/i8+ws3IwJyTp9s7/wIayoMvjDQrF9kq18o4PHDlrHg9Ho9APF49Xan92ipiXq5gJrYUC0V5PPkjZLMqnX9vCQfu1xE40oRY5dCNK8O493WLhY6o8+PLdHP330ZtYpMRe26/iAjl/vhuh/AE89nTjsAkEKKgDbv/fHkrJyF9kCS0OXxcCYbmWg+cDkApJCZAUVFzqyozsqRIqB1pZ1uB4AkUiI/e7kWPJgeheuFJVBOdOIkiRTftrH64StePOkaIqcyoI2qRHGUcbRcrKvSmQRhlgCMkalB/4APItS1oJnqn+hQo30BGCNF4Hoce/suOGkg7nCz6ihBRHdEpgdFBDzqrGNFphYkDUhkysQWDJSNLjrZDEeOLQMAYIxMgv2+J6KJxDykQxxJqr072cdUWmSxaX07Puj034J61ztL16c4dBYADKSOCnEclBY6dXb/dpXdm6yy2XZF4m57hE23RlhnvMxmWhXWnaiwuYkqmxPfzN+psfmpOptqlllx6NzrIzMQ589TAPhX+P//0XIn+AvU+Rz5ggypoQAAAABJRU5ErkJggg==)
-}
-.icondoc {
-    width: 24px;
-    height: 18px;
-    margin-bottom: 4px;
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAWCAYAAADafVyIAAACsUlEQVR4Ae2dTU9TWxiFn55z+mE/LVhaKFAVRBI0gh8gQQZXYnVgYgwJNzd35EhGxhlDy9SBf8L/4C9gdm+EARGIQVAD8nGLUKBAC6373QUT6Dk4MAzu4KQru6fdedde71rvOVNXuVwGODMYAGeJMyewAE7iw6dsubhfYq9woO/l+8ZWgdzWHqGAB5/XIqzWhliAZF3QBeAEM5PJABzDxMx/mXiNn6DfTeCcWxc851NQa3Zjl2jIJ4WZmF7FbRmZaNg3CmAH2xaZpgvDqMDlcuFxmwQVkZy+IRZkYWVLn/7G1Zg6zCqzX9cdk+LogWkaP0kElmUQUCpCATefv+X0HiG53RFncjbLcjZvS2Lrgf7j8PRySZTLVIj8qoyoePP2PZv5oiaJKGUr3/PEa/0Ax2DrwdxiLpO4ENAFV9d3MKWwatF6TpmsfKlXReO1AaJhrzZb9liGQWvT+SovnBWoFomAyY9ZraD/VpJ/p5Z1smrCPjFXCioVBb1/t7APUAVHD456/6gvRWd7DJ/H4mFvisGBVvo6G+i/maQxESQS9FKnElcslgCq4KhAiss1Nr7A1NwaLY0Rvixt6rjOL+bouZYgEvJyNRWlVCpTKFZmBjj2OXWSDdWjB3eb+fNhGwM9zTx70qFVjA73cq8ryeVkRM9GJOgBsIWjAum/YHr+u8769k6RtdyuHjBRM6N+X17L8+KvTj2IAHZwVOCxTJ2eVH2I7mtxhtJtPB+8ztM/Wmi/WKPvX/7dpVspgwlgB2fqw2EbG1/UKuTUMmAnPZD1tEb/MkXiwVD6Cve7m2w9kDiLVwB2sCWQVEhxyb88IqTvRw++xnhIeyPG1qth1ErV3gOHF5dti4Sg5/EIS3P/4PFWigDYobC3TeLSHV6NDANUwZYg3Ztypd+9Bvht/P9fmT8AqlfEsPcjdQ8AAAAASUVORK5CYII=);
-    background-position: 0 -4px;
-    background-repeat: repeat-y;
-    vertical-align: top;
-    display: inline-block
-}
-table.directory {
-    font: 400 14px "Contax Pro", sans-serif
-}
-div.dynheader {
-    margin-top: 8px;
-    -webkit-touch-callout: none;
-    -webkit-user-select: none;
-    -moz-user-select: none;
-    -ms-user-select: none;
-    user-select: none
-}
-address {
-    font-style: normal;
-    color: #2a3d61
-}
-table.doxtable caption {
-    caption-side: top
-}
-table.doxtable {
-    border-collapse: collapse;
-    margin-top: 4px;
-    margin-bottom: 4px
-}
-table.doxtable td,
-table.doxtable th {
-    border: 1px solid #2d4068;
-    padding: 3px 7px 2px
-}
-table.doxtable th {
-    background-color: #374f7f;
-    color: #fff;
-    font-size: 110%;
-    padding-bottom: 4px;
-    padding-top: 5px
-}
-table.fieldtable {
-    margin-bottom: 10px;
-    border: 1px solid #a8b8d9;
-    border-spacing: 0;
-    border-radius: 4px;
-    box-shadow: 2px 2px 2px rgba(0, 0, 0, .15)
-}
-.fieldtable td,
-.fieldtable th {
-    padding: 3px 7px 2px
-}
-.fieldtable td.fieldname,
-.fieldtable td.fieldtype {
-    white-space: nowrap;
-    border-right: 1px solid #a8b8d9;
-    border-bottom: 1px solid #a8b8d9;
-    vertical-align: top
-}
-.fieldtable td.fieldname {
-    padding-top: 3px
-}
-.fieldtable td.fielddoc {
-    border-bottom: 1px solid #a8b8d9
-}
-.fieldtable td.fielddoc p:first-child {
-    margin-top: 0
-}
-.fieldtable td.fielddoc p:last-child {
-    margin-bottom: 2px
-}
-.fieldtable tr:last-child td {
-    border-bottom: none
-}
-.fieldtable th {
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA4CAIAAACzAgW7AAAAYElEQVR4Ae3dSw6AIAxF0Za3WweG+IFC0W1r4sTCSBwYl3By07wugo7zguqOpBtSNlogVkkFsRJFkII1arOEbBTzmptpSZis3urnSjCM0RHRL477m5kdEXX48fPevzZzA0gYIN0BAPV5AAAAAElFTkSuQmCC);
-    background-repeat: repeat-x;
-    background-color: #e2e8f2;
-    font-size: 90%;
-    color: #253555;
-    padding-bottom: 4px;
-    padding-top: 5px;
-    text-align: left;
-    font-weight: 400;
-    -moz-border-radius-topleft: 4px;
-    -moz-border-radius-topright: 4px;
-    -webkit-border-top-left-radius: 4px;
-    -webkit-border-top-right-radius: 4px;
-    border-top-left-radius: 4px;
-    border-top-right-radius: 4px;
-    border-bottom: 1px solid #a8b8d9
-}
-.tabsearch {
-    top: 0;
-    left: 10px;
-    height: 36px;
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAIAAADHFsdbAAAAcElEQVR4Ae3dTQ6DIBRF4ce70NS4uA51YOLAtFYw0B+gxn06dAddRMGykHO/5K6Ctv3LdaX4fJJ4+RXuvcA+/xkXMbsPJhugbcQ4B9xT2dF43EzAVfscExGa3rIQxGkORZaK5U9zhKKSGYFueODS6h/TSxpOsn4UagAAAABJRU5ErkJggg==);
-    z-index: 101;
-    overflow: hidden;
-    font-size: 13px
-}
-.navpath ul {
-    font-size: 11px;
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAIAAADHFsdbAAAAcElEQVR4Ae3dTQ6DIBRF4ce70NS4uA51YOLAtFYw0B+gxn06dAddRMGykHO/5K6Ctv3LdaX4fJJ4+RXuvcA+/xkXMbsPJhugbcQ4B9xT2dF43EzAVfscExGa3rIQxGkORZaK5U9zhKKSGYFueODS6h/TSxpOsn4UagAAAABJRU5ErkJggg==);
-    background-repeat: repeat-x;
-    background-position: 0 -5px;
-    height: 30px;
-    line-height: 30px;
-    color: #8aa0cc;
-    border: 1px solid #c2cde4;
-    overflow: hidden;
-    margin: 0;
-    padding: 0
-}
-.navpath li {
-    list-style-type: none;
-    float: left;
-    padding-left: 10px;
-    padding-right: 15px;
-    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAeCAYAAAARgF8NAAACa0lEQVR4Ae2dy2sTURTGz525ycykSSaTpg9tmiYxNTYqbsSFlAbcuJBSLDQLK0i1KFUbrWKUqhQxgoqIj0oXLrooRbdtEd+P+mjrSm1LUydDmyiC6OTRhaQIEu8MJuTW/guH73LO5fzuvZwzZ/Yoevf90iZfORDzfZLVnwBAiW3adSBgEgzYaGDx99SvCQCghPoGJrfxHB7x19l+k72X3PKHAs7d0Q9NNLgliTOypz/K6mgpgP/5gR+ZXMRZaT5KYgpAZ/vfad6IEPqy0WtnGQYFp+PqXBHova0DmkWdVeaddis/RYDuInDm1ttCXINZJhbw2PMkdk0r6pIORG68KX3y/jqnWG/iDYMzitqvAyevvy4FgmbBMOx1ijnyTP1qgGYfNrglqwEzR2aU1CPUc20cACgdLBf5w2sqypKzSqoFha+8AgBKAsuib+QWhpS8FXVffgkAsHJdJSUHbRZuHHVdeg4AsHI1W83GsKva8pUBAFhltZKGSfk8yOjQxWcAQEnU2t7gteszgjovPAUASsccktBRKQnxuYV0G9rf9wQAKE37XDYz6UNnbCH9Au07/7g02Wji8T33WusyOa13kt3StLcUiFY7ykwYM4NqJjept7q992EhSYYBKevrJC32xxbT+gCzmxuLN3RJVr5W4PHU/GJmqDgPociDQjzvq7VpbW7/nMgUh4QNbN+j+R0Ch9tEC5cjyQg1k60nxjQ/7Kyy+E0CHpITmZsUsLtnrIJ8NcXnErW9R05k0xTQcnz0lMMmhOwiNysnsx0AQAk1h0finhqRxxiF4smsXjv145CWLjMI0nIi/V9Ss7/CQLJvSb7lJAAAAABJRU5ErkJggg==);
-    background-repeat: no-repeat;
-    background-position: 100%;
-    color: #364d7c
-}
-.navpath li.navelem a {
-    height: 32px;
-    display: block;
-    outline: none;
-    color: #283a5d;
-    font-family: Lucida Grande, Geneva, Helvetica, Arial, sans-serif;
-    text-shadow: 0 1px 1px hsla(0, 0%, 100%, .9);
-    text-decoration: none
-}
-.navpath li.navelem a:hover {
-    color: #6884bd
-}
-.navpath li.footer {
-    list-style-type: none;
-    float: right;
-    padding-left: 10px;
-    padding-right: 15px;
-    background-image: none;
-    background-repeat: no-repeat;
-    background-position: 100%;
-    color: #364d7c;
-    font-size: 8pt
-}
-div.summary {
-    float: right;
-    font-size: 8pt;
-    padding-right: 5px;
-    width: 50%;
-    text-align: right
-}
-div.summary a,
-table.classindex {
-    white-space: nowrap
-}
-table.classindex {
-    margin: 10px;
-    margin-left: 3%;
-    margin-right: 3%;
-    width: 94%;
-    border: 0;
-    border-spacing: 0;
-    padding: 0
-}
-div.ingroups {
-    font-size: 8pt;
-    width: 50%;
-    text-align: left
-}
-div.ingroups a {
-    white-space: nowrap
-}
-div.header {
-    background-color: #f9fafc;
-    margin: 0;
-    border-bottom: 1px solid #c4cfe5
-}
-div.headertitle {
-    padding: 5px 5px 5px 10px
-}
-dl {
-    padding: 0 0 0 10px
-}
-dl.section {
-    margin-left: 0;
-    padding-left: 0
-}
-dl.note {
-    border-color: #d0c000
-}
-dl.attention,
-dl.note,
-dl.warning {
-    margin-left: -7px;
-    padding-left: 3px;
-    border-left: 4px solid
-}
-dl.attention,
-dl.warning {
-    border-color: red
-}
-dl.invariant,
-dl.post,
-dl.pre {
-    border-color: #00d000
-}
-dl.deprecated,
-dl.invariant,
-dl.post,
-dl.pre {
-    margin-left: -7px;
-    padding-left: 3px;
-    border-left: 4px solid
-}
-dl.deprecated {
-    border-color: #505050
-}
-dl.todo {
-    border-color: #00c0e0
-}
-dl.test,
-dl.todo {
-    margin-left: -7px;
-    padding-left: 3px;
-    border-left: 4px solid
-}
-dl.test {
-    border-color: #3030e0
-}
-dl.bug {
-    margin-left: -7px;
-    padding-left: 3px;
-    border-left: 4px solid;
-    border-color: #c08050
-}
-dl.section dd {
-    margin-bottom: 6px
-}
-#projectlogo {
-    text-align: center;
-    vertical-align: bottom;
-    border-collapse: separate
-}
-#projectlogo img {
-    border: 0 none
-}
-#projectalign {
-    vertical-align: middle
-}
-#projectname {
-    font: 300% Tahoma, Arial, sans-serif;
-    margin: 0;
-    padding: 2px 0
-}
-#projectbrief {
-    font: 120% Tahoma, Arial, sans-serif;
-    margin: 0;
-    padding: 0
-}
-#projectnumber {
-    font: 50% Tahoma, Arial, sans-serif;
-    margin: 0;
-    padding: 0
-}
-#titlearea {
-    padding: 0;
-    margin: 0;
-    width: 100%;
-    border-bottom: 1px solid #dcd9d9
-}
-.diagraph,
-.dotgraph,
-.image,
-.mscgraph {
-    text-align: center
-}
-.caption {
-    font-weight: 700
-}
-div.zoom {
-    border: 1px solid #90a5ce
-}
-dl.citelist {
-    margin-bottom: 50px
-}
-dl.citelist dt {
-    color: #334975;
-    float: left;
-    font-weight: 700;
-    margin-right: 10px;
-    padding: 5px
-}
-dl.citelist dd {
-    margin: 2px 0;
-    padding: 5px 0
-}
-div.toc {
-    padding: 14px 25px;
-    background-color: #f4f6fa;
-    border: 1px solid #d8dfee;
-    border-radius: 7px 7px 7px 7px;
-    float: right;
-    height: auto;
-    margin: 0 8px 10px 10px;
-    width: 200px
-}
-div.toc li {
-    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAWklEQVR4Ae2dyw2AIBBEn1CWMfFsG55twAtysQFqsi5lDOiGRFvYyb7Zz9QAvLWm47TeAXzpf5mjNoBWmusztAfFBz9Mcycofaw+KwqeS/Mc96W/YxFoYBeCC17XGwSD3o1uAAAAAElFTkSuQmCC) no-repeat scroll 0 5px transparent;
-    font: 10px/1.2 Verdana, DejaVu Sans, Geneva, sans-serif;
-    margin-top: 5px;
-    padding-left: 10px;
-    padding-top: 2px
-}
-div.toc h3 {
-    font: 700 12px/1.2 Arial, FreeSans, sans-serif;
-    color: #4665a2;
-    border-bottom: 0 none;
-    margin: 0
-}
-div.toc ul {
-    list-style: none outside none;
-    border: medium none;
-    padding: 0
-}
-div.toc li.level1 {
-    margin-left: 0
-}
-div.toc li.level2 {
-    margin-left: 15px
-}
-div.toc li.level3 {
-    margin-left: 30px
-}
-div.toc li.level4 {
-    margin-left: 45px
-}
-.inherit_header {
-    font-weight: 700;
-    color: gray;
-    cursor: pointer;
-    -webkit-touch-callout: none;
-    -webkit-user-select: none;
-    -moz-user-select: none;
-    -ms-user-select: none;
-    user-select: none
-}
-.inherit_header td {
-    padding: 6px 0 2px 5px
-}
-.inherit {
-    display: none
-}
-tr.heading h2 {
-    margin-top: 12px;
-    margin-bottom: 4px
-}
-#powerTip,
-.ttc {
-    position: absolute;
-    display: none
-}
-#powerTip {
-    cursor: default;
-    white-space: nowrap;
-    background-color: #fff;
-    border: 1px solid gray;
-    border-radius: 4px 4px 4px 4px;
-    box-shadow: 1px 1px 7px gray;
-    font-size: smaller;
-    max-width: 80%;
-    opacity: .9;
-    padding: 1ex 1em 1em;
-    z-index: 2147483647
-}
-#powerTip div.ttdoc {
-    color: grey;
-    font-style: italic
-}
-#powerTip div.ttname,
-#powerTip div.ttname a {
-    font-weight: 700
-}
-#powerTip div.ttdeci {
-    color: #006318
-}
-#powerTip div {
-    margin: 0;
-    padding: 0;
-    font: 12px/16px "Contax Pro", sans-serif
-}
-#powerTip:after,
-#powerTip:before {
-    content: "";
-    position: absolute;
-    margin: 0
-}
-#powerTip.e:after,
-#powerTip.e:before,
-#powerTip.n:after,
-#powerTip.n:before,
-#powerTip.ne:after,
-#powerTip.ne:before,
-#powerTip.nw:after,
-#powerTip.nw:before,
-#powerTip.s:after,
-#powerTip.s:before,
-#powerTip.se:after,
-#powerTip.se:before,
-#powerTip.sw:after,
-#powerTip.sw:before,
-#powerTip.w:after,
-#powerTip.w:before {
-    border: solid transparent;
-    content: " ";
-    height: 0;
-    width: 0;
-    position: absolute
-}
-#powerTip.e:after,
-#powerTip.n:after,
-#powerTip.ne:after,
-#powerTip.nw:after,
-#powerTip.s:after,
-#powerTip.se:after,
-#powerTip.sw:after,
-#powerTip.w:after {
-    border-color: hsla(0, 0%, 100%, 0)
-}
-#powerTip.e:before,
-#powerTip.n:before,
-#powerTip.ne:before,
-#powerTip.nw:before,
-#powerTip.s:before,
-#powerTip.se:before,
-#powerTip.sw:before,
-#powerTip.w:before {
-    border-color: hsla(0, 0%, 50%, 0)
-}
-#powerTip.n:after,
-#powerTip.n:before,
-#powerTip.ne:after,
-#powerTip.ne:before,
-#powerTip.nw:after,
-#powerTip.nw:before {
-    top: 100%
-}
-#powerTip.n:after,
-#powerTip.ne:after,
-#powerTip.nw:after {
-    border-top-color: #fff;
-    border-width: 10px;
-    margin: 0 -10px
-}
-#powerTip.n:before {
-    border-top-color: gray;
-    border-width: 11px;
-    margin: 0 -11px
-}
-#powerTip.n:after,
-#powerTip.n:before {
-    left: 50%
-}
-#powerTip.nw:after,
-#powerTip.nw:before {
-    right: 14px
-}
-#powerTip.ne:after,
-#powerTip.ne:before {
-    left: 14px
-}
-#powerTip.s:after,
-#powerTip.s:before,
-#powerTip.se:after,
-#powerTip.se:before,
-#powerTip.sw:after,
-#powerTip.sw:before {
-    bottom: 100%
-}
-#powerTip.s:after,
-#powerTip.se:after,
-#powerTip.sw:after {
-    border-bottom-color: #fff;
-    border-width: 10px;
-    margin: 0 -10px
-}
-#powerTip.s:before,
-#powerTip.se:before,
-#powerTip.sw:before {
-    border-bottom-color: gray;
-    border-width: 11px;
-    margin: 0 -11px
-}
-#powerTip.s:after,
-#powerTip.s:before {
-    left: 50%
-}
-#powerTip.sw:after,
-#powerTip.sw:before {
-    right: 14px
-}
-#powerTip.se:after,
-#powerTip.se:before {
-    left: 14px
-}
-#powerTip.e:after,
-#powerTip.e:before {
-    left: 100%
-}
-#powerTip.e:after {
-    border-left-color: #fff;
-    border-width: 10px;
-    top: 50%;
-    margin-top: -10px
-}
-#powerTip.e:before {
-    border-left-color: gray;
-    border-width: 11px;
-    top: 50%;
-    margin-top: -11px
-}
-#powerTip.w:after,
-#powerTip.w:before {
-    right: 100%
-}
-#powerTip.w:after {
-    border-right-color: #fff;
-    border-width: 10px;
-    top: 50%;
-    margin-top: -10px
-}
-#powerTip.w:before {
-    border-right-color: gray;
-    border-width: 11px;
-    top: 50%;
-    margin-top: -11px
-}
-@media print {
-    #nav-path,
-    #side-nav,
-    #top {
-        display: none
-    }
-    body {
-        overflow: visible
-    }
-    h1,
-    h2,
-    h3,
-    h4,
-    h5,
-    h6 {
-        page-break-after: avoid
-    }
-    .summary {
-        display: none
-    }
-    .memitem {
-        page-break-inside: avoid
-    }
-    #doc-content {
-        margin-left: 0!important;
-        height: auto!important;
-        width: auto!important;
-        overflow: inherit;
-        display: inline
-    }
-}
-body,
-input {
-    font-family: Open Sans, Helvetica, sans-serif;
-    color: #323d47;
-    background: #fbfbfb
-}
-a {
-    color: #4665a2
-}
-#projectname,
-.title,
-h1,
-h2 {
-    font-family: Contax Pro, HelveticaNeue, Helvetica Neue, HelveticaNeueRoman, HelveticaNeue-Roman, Helvetica Neue Roman, Helvetica, Tahoma, Geneva, Arial, sans-serif;
-    font-weight: 900;
-}
-#projectname,
-.title {
-    font-size: 32px
-}
-h1 {
-    font-size: 24px;
-}
-h2 {
-    font-size: 20px;
-}
-hr {
-    border-top: 1px solid #f59cad
-}
-#projectname {
-    padding-left: 20px
-}
-#MSearchField {
-    padding: 0 0 0 .5em;
-    font-size: 1em
-}
-#MSearchSelectWindow {
-    border: 1px solid #f59cad
-}
-a.SelectItem:hover {
-    background: #fbfbfb;
-    color: #000
-}
-#MSearchResultsWindow {
-    background: #fbfbfb;
-    border-radius: 3px
-}
-#nav-tree {
-    padding-left: 20px
-}
-#nav-tree .selected {
-    font-weight: 700
-}
-.arrow {
-    color: #d1d3d3
-}
-.item:hover>a>.arrow {
-    color: #aaaeae
-}
-.ui-resizable-e {
-    border-style: solid;
-    border-width: 0 1px;
-    border-color: #dcd9d9
-}
-.ui-resizable-e:before {
-    content: '';
-    display: block;
-    position: absolute;
-    top: 50%;
-    margin-top: -8px;
-    width: 3px;
-    height: 3px;
-    border-style: double;
-    border-width: 6px 0;
-    border-color: #fbfbfb;
-    margin-left: 2px
-}
-div.header {
-    background: #fbfbfb;
-    border: 0
-}
-h2.groupheader {
-    color: #000;
-    border-bottom: 1px solid #f59cad
-}
-.memSeparator {
-    border-bottom: 1px solid #f8ccd4
-}
-/*# sourceMappingURL=doxygen.css.map*/
-
-div.image img[src="BlocksMonitor.png"] {
-    width: 750px;
-}
-div.image img[src="BlocksDrawing_palette.JPG"] {
-    width: 320px;
-}
-div.image img[src="BlocksDrawing_canvas.JPG"] {
-    width: 320px;
-}
-div.image img[src="BlocksSynth_grid.JPG"] {
-    width: 320px;
-}
-div.image img[src="BlocksSynth_waveshape.gif"] {
-    width: 320px;
-}
index 30293d72e9e680318418f95a67a5ad6cdeeda20c..2bdd7234505574ef952e551316964f6c7ab2b9d7 100644 (file)
@@ -6,19 +6,19 @@ This repository contains the source code of the BLOCKS SDK, which is licensed un
 
 Much more comprehensive documentation can be found at http://developer.roli.com/documentation/the_standalone_blocks_sdk.html.
 
-The `SDK` directory contains the source code required to compile a library containing the BLOCKS SDK functionality. In the `SDK/Build` directory you will find an Xcode project, a Visual Studio solution and a Linux Makefile which are configured to create a static library on the MacOS, Windows and Linux platforms respectively. Simply use the one appropriate for your system. Once you have created this library you can access BLOCKS functionality by linking this library into your application and `#include`-ing the provided header file, `BlocksHeader.h`.
+The `SDK` directory contains the source code required to compile a library containing the BLOCKS SDK functionality. In the `SDK/Build` directory you will find an Xcode project, a Visual Studio solution and a Linux Makefile which are configured to create a static library on the macOS, Windows and Linux platforms respectively. Simply use the one appropriate for your system. Once you have created this library you can access BLOCKS functionality by linking this library into your application and `#include`-ing the provided header file, `BlocksHeader.h`.
 
-The `examples` directory contains some sample code which uses the BLOCKS SDK library. Here we again provide an Xcode project, a Visual Studio solution and a Linux Makefile to allow the examples to be built on the corresponding platform. The Xcode project and Visual Studio solution compile the BLOCKS SDK library automatically, whereas the Linux Makefile requires the BLOCKS SDK library to be manually build first.
+The `examples` directory contains some sample code which uses the BLOCKS SDK library. Here we again provide an Xcode project, a Visual Studio solution and a Linux Makefile to allow the examples to be built on the corresponding platform. The Xcode project and Visual Studio solution compile the BLOCKS SDK library automatically, whereas the Linux Makefile requires the BLOCKS SDK library to be manually built first.
 
 ## Quick start guide
 
-### MacOS with Xcode
+### macOS with Xcode
 
 Open `examples/BlockFinder/MacOS/BlockFinder.xcodeproj` with Xcode and compile and execute the example application. This will both create the BLOCKS SDK library and provide a very simple demonstration of how to use it. Use this as a base to develop your own BLOCKS creation!
 
 ### Windows with Visual Studio
 
-Use the same procedure as MacOS, but instead open `examples/BlockFinder/Windows/BlockFinder.vcxproj`.
+Use the same procedure as macOS, but instead open `examples/BlockFinder/Windows/BlockFinder.vcxproj`.
 
 ### Linux
 
@@ -39,21 +39,21 @@ This will produce the executable `BlockFinder` in the `Debug` directory.
 
 The source code for the BLOCKS SDK library is contained within the `SDK` directory of this repository.  Here you will find header files that you can include in your own projects and the `Build` subdirectory contains an Xcode project, a Visual Studio project and a Linux Makefile for compiling the SDK source code into a static library. Use the appropriate choice for your platform, select either the "Debug" or "Release" configuration, and build the project.
 
-For MacOS this will produce `libBLOCKS-SDK.a` in either the `SDK/Build/MacOS/Debug/` or `SDK/Build/MacOS/Release/` directory, for Linux this will produce `libBLOCKS-SDK.a` in either the `SDK/Build/Linux/Debug/` or `SDK/Build/Linux/Release/` directory, and for Windows this will produce `BLOCKS-SDK.lib` in either the `SDK\Build\Windows\x64\Debug` or `SDK\Build\Windows\x64\Release` folder.
+For macOS this will produce `libBLOCKS-SDK.a` in either the `SDK/Build/MacOS/Debug/` or `SDK/Build/MacOS/Release/` directory, for Linux this will produce `libBLOCKS-SDK.a` in either the `SDK/Build/Linux/Debug/` or `SDK/Build/Linux/Release/` directory, and for Windows this will produce `BLOCKS-SDK.lib` in either the `SDK\Build\Windows\x64\Debug` or `SDK\Build\Windows\x64\Release` folder.
 
 ### Using the SDK header file
 
-To use BLOCKS classes and functions in your application you must include the `BlocksHeader.h` file in your source code. You also need to tell the compiler to look in the `SDK` directory for additional header files, which you can configure inside your Xcode or Visual Studio project. If you are using the command line to compile your application then you can see an example of how to do this in `examples/BLOCKS-SDK/BlockFinder/Linux/Makefile` (which is also configured for MacOS, despite being located inside the Linux directory).
+To use BLOCKS classes and functions in your application you must include the `BlocksHeader.h` file in your source code. You also need to tell the compiler to look in the `SDK` directory for additional header files, which you can configure inside your Xcode or Visual Studio project. If you are using the command line to compile your application then you can see an example of how to do this in `examples/BlockFinder/Linux/Makefile` or `examples/BlockFinder/MacOS/Makefile`.
 
 ### Linking against the SDK library
 
-You must also tell your compiler where to find the SDK static library before your BLOCKS application will compile, and include all of the dependencies for your platform, which are listed in the Dependencies section of this README. Again, this is configured in your Xcode or Visual Studio project, but if you are using the command line you can see an example of how to do this in `examples/BLOCKS-SDK/BlockFinder/Linux/Makefile` (which, again, is also configured for MacOS).
+You must also tell your compiler where to find the SDK static library before your BLOCKS application will compile, and include all of the dependencies for your platform, which are listed in the Dependencies section of this README. Again, this is configured in your Xcode or Visual Studio project, but if you are using the command line you can see an example of how to do this in `examples/BlockFinder/Linux/Makefile` or `examples/BlockFinder/MacOS/Makefile`.
 
 ## Dependencies
 
 - A C++11 compatible compiler
 
-### MacOS frameworks
+### macOS frameworks
 
 - Accelerate
 - AudioToolbox
index b7c0aabf239ace85b32789fa7883832b15ab2f40..78c6da9cb91b70105e1fab50ff22c87ff4f01d0d 100644 (file)
@@ -1,11 +1,11 @@
 #pragma once\r
 \r
 #ifndef JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED\r
-#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1\r
+ #define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1\r
 #endif\r
 \r
 #ifndef JUCE_DONT_DECLARE_PROJECTINFO\r
-#define JUCE_DONT_DECLARE_PROJECTINFO 1\r
+ #define JUCE_DONT_DECLARE_PROJECTINFO 1\r
 #endif\r
 \r
 #include <juce_audio_basics/juce_audio_basics.h>\r
index 77cbb25291beaabc705038fbfe1d402ed943ff6a..7622facbd2eb8550185e2c4eab7fefabcdcf964e 100644 (file)
@@ -1,21 +1,18 @@
 /*\r
   ==============================================================================\r
 \r
-   This file is part of the JUCE library.\r
+   This file is part of the JUCE examples.\r
    Copyright (c) 2017 - ROLI Ltd.\r
 \r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
    The code included in this file is provided under the terms of the ISC license\r
    http://www.isc.org/downloads/software-support-policy/isc-license. Permission\r
    To use, copy, modify, and/or distribute this software for any purpose with or\r
    without fee is hereby granted provided that the above copyright notice and\r
    this permission notice appear in all copies.\r
 \r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
+   THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES,\r
+   WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR\r
+   PURPOSE, ARE DISCLAIMED.\r
 \r
   ==============================================================================\r
 */\r
@@ -34,18 +31,19 @@ void BlockFinder::topologyChanged()
 {\r
     // We have a new topology, so find out what it isand store it in a local\r
     // variable.\r
-    BlockTopology currentTopology = pts.getCurrentTopology();\r
+    auto currentTopology = pts.getCurrentTopology();\r
     Logger::writeToLog ("\nNew BLOCKS topology.");\r
 \r
     // The blocks member of a BlockTopology contains an array of blocks. Here we\r
     // loop over them and print some information.\r
-    Logger::writeToLog (String ("Detected ") + String (currentTopology.blocks.size()) + " blocks:");\r
+    Logger::writeToLog ("Detected " + String (currentTopology.blocks.size()) + " blocks:");\r
+\r
     for (auto& block : currentTopology.blocks)\r
     {\r
         Logger::writeToLog ("");\r
-        Logger::writeToLog (String("    Description:   ") + block->getDeviceDescription());\r
-        Logger::writeToLog (String("    Battery level: ") + String (block->getBatteryLevel()));\r
-        Logger::writeToLog (String("    UID:           ") + String (block->uid));\r
-        Logger::writeToLog (String("    Serial number: ") + block->serialNumber);\r
+        Logger::writeToLog ("    Description:   " + block->getDeviceDescription());\r
+        Logger::writeToLog ("    Battery level: " + String (block->getBatteryLevel()));\r
+        Logger::writeToLog ("    UID:           " + String (block->uid));\r
+        Logger::writeToLog ("    Serial number: " + block->serialNumber);\r
     }\r
 }\r
index 7a0db7d8a9e6cb065e74e3e472f694f204acd3aa..2366c7aaae49987420ffc87715578f94107f9127 100644 (file)
@@ -1,21 +1,18 @@
 /*\r
   ==============================================================================\r
 \r
-   This file is part of the JUCE library.\r
+   This file is part of the JUCE examples.\r
    Copyright (c) 2017 - ROLI Ltd.\r
 \r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
    The code included in this file is provided under the terms of the ISC license\r
    http://www.isc.org/downloads/software-support-policy/isc-license. Permission\r
    To use, copy, modify, and/or distribute this software for any purpose with or\r
    without fee is hereby granted provided that the above copyright notice and\r
    this permission notice appear in all copies.\r
 \r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
+   THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES,\r
+   WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR\r
+   PURPOSE, ARE DISCLAIMED.\r
 \r
   ==============================================================================\r
 */\r
index c591de310b1997f5aca93d8d9311c516668dda25..f05c77ca835ede698a56ada43c0a93ca646505e6 100644 (file)
@@ -1,21 +1,18 @@
 /*\r
   ==============================================================================\r
 \r
-   This file is part of the JUCE library.\r
+   This file is part of the JUCE examples.\r
    Copyright (c) 2017 - ROLI Ltd.\r
 \r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
    The code included in this file is provided under the terms of the ISC license\r
    http://www.isc.org/downloads/software-support-policy/isc-license. Permission\r
    To use, copy, modify, and/or distribute this software for any purpose with or\r
    without fee is hereby granted provided that the above copyright notice and\r
    this permission notice appear in all copies.\r
 \r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
+   THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES,\r
+   WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR\r
+   PURPOSE, ARE DISCLAIMED.\r
 \r
   ==============================================================================\r
 */\r
@@ -29,20 +26,22 @@ class MyJUCEApp  : public juce::JUCEApplicationBase
 public:\r
     MyJUCEApp()  {}\r
     ~MyJUCEApp() {}\r
+\r
     void initialise (const juce::String&) override {}\r
-    void shutdown() override {}\r
-    const juce::String getApplicationName() override { return "BlockFinder"; }\r
-    const juce::String getApplicationVersion() override { return "1.0.0"; }\r
-    bool moreThanOneInstanceAllowed() override { return true; }\r
+    void shutdown() override                       {}\r
+\r
+    const juce::String getApplicationName() override           { return "BlockFinder"; }\r
+    const juce::String getApplicationVersion() override        { return "1.0.0"; }\r
+    bool moreThanOneInstanceAllowed() override                 { return true; }\r
     void anotherInstanceStarted (const juce::String&) override {}\r
-    void suspended() override {}\r
-    void resumed() override {}\r
+\r
+    void suspended() override           {}\r
+    void resumed() override             {}\r
     void systemRequestedQuit() override {}\r
     void unhandledException(const std::exception*, const juce::String&,\r
                             int lineNumber) override {}\r
 \r
 private:\r
-\r
     // Our BLOCKS class.\r
     BlockFinder finder;\r
 };\r
index 507a13b76316d01107a6b009fcbdca346d1b3619..1474023b67321ec3d95f4062fc7b475015427688 100644 (file)
@@ -42,7 +42,7 @@ INCLUDES := -I$(SDK_PATH)
 ifeq ($(PLATFORM),MacOS)
     LIBS := -framework Accelerate -framework AudioToolbox -framework Carbon -framework Cocoa -framework CoreAudio -framework CoreMIDI -framework IOKit -framework OpenGL -framework QuartzCore
 else
-    LIBS := -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa freetype2 libcurl x11 xext xinerama) -lGL -ldl -lpthread -lrt
+    LIBS := -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa libcurl x11) -ldl -lpthread -lrt
     CXXFLAGS += -DLINUX=1
 endif
 
index bfc74c8e48520890610bb97fb234bb69fe5ad739..ba02d820f3ea5e3d262eeb5633224c096ca7d205 100644 (file)
@@ -1,21 +1,18 @@
 /*\r
   ==============================================================================\r
 \r
-   This file is part of the JUCE library.\r
+   This file is part of the JUCE examples.\r
    Copyright (c) 2017 - ROLI Ltd.\r
 \r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
    The code included in this file is provided under the terms of the ISC license\r
    http://www.isc.org/downloads/software-support-policy/isc-license. Permission\r
    To use, copy, modify, and/or distribute this software for any purpose with or\r
    without fee is hereby granted provided that the above copyright notice and\r
    this permission notice appear in all copies.\r
 \r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
+   THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES,\r
+   WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR\r
+   PURPOSE, ARE DISCLAIMED.\r
 \r
   ==============================================================================\r
 */\r
index c591de310b1997f5aca93d8d9311c516668dda25..f05c77ca835ede698a56ada43c0a93ca646505e6 100644 (file)
@@ -1,21 +1,18 @@
 /*\r
   ==============================================================================\r
 \r
-   This file is part of the JUCE library.\r
+   This file is part of the JUCE examples.\r
    Copyright (c) 2017 - ROLI Ltd.\r
 \r
-   JUCE is an open source library subject to commercial or open-source\r
-   licensing.\r
-\r
    The code included in this file is provided under the terms of the ISC license\r
    http://www.isc.org/downloads/software-support-policy/isc-license. Permission\r
    To use, copy, modify, and/or distribute this software for any purpose with or\r
    without fee is hereby granted provided that the above copyright notice and\r
    this permission notice appear in all copies.\r
 \r
-   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
-   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
-   DISCLAIMED.\r
+   THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES,\r
+   WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR\r
+   PURPOSE, ARE DISCLAIMED.\r
 \r
   ==============================================================================\r
 */\r
@@ -29,20 +26,22 @@ class MyJUCEApp  : public juce::JUCEApplicationBase
 public:\r
     MyJUCEApp()  {}\r
     ~MyJUCEApp() {}\r
+\r
     void initialise (const juce::String&) override {}\r
-    void shutdown() override {}\r
-    const juce::String getApplicationName() override { return "BlockFinder"; }\r
-    const juce::String getApplicationVersion() override { return "1.0.0"; }\r
-    bool moreThanOneInstanceAllowed() override { return true; }\r
+    void shutdown() override                       {}\r
+\r
+    const juce::String getApplicationName() override           { return "BlockFinder"; }\r
+    const juce::String getApplicationVersion() override        { return "1.0.0"; }\r
+    bool moreThanOneInstanceAllowed() override                 { return true; }\r
     void anotherInstanceStarted (const juce::String&) override {}\r
-    void suspended() override {}\r
-    void resumed() override {}\r
+\r
+    void suspended() override           {}\r
+    void resumed() override             {}\r
     void systemRequestedQuit() override {}\r
     void unhandledException(const std::exception*, const juce::String&,\r
                             int lineNumber) override {}\r
 \r
 private:\r
-\r
     // Our BLOCKS class.\r
     BlockFinder finder;\r
 };\r
index efcc92257aab5e912e0ab3316dc3f06b73be4026..004beb573a68243b413d400c528d6a3a4a745707 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 \r
 <JUCERPROJECT id="3t6YqETY1" name="BinaryBuilder" projectType="consoleapp"\r
-              juceFolder="../../../juce" jucerVersion="5.3.0" bundleIdentifier="com.roli.binarybuilder"\r
+              juceFolder="../../../juce" jucerVersion="5.3.1" bundleIdentifier="com.roli.binarybuilder"\r
               displaySplashScreen="0" reportAppUsage="0" companyName="ROLI Ltd."\r
               companyCopyright="ROLI Ltd.">\r
   <EXPORTFORMATS>\r
index 7bbadf2981bfa9045b1e9d045307968151de0f3f..da821bb39ca252ef485294b4e7ed98773ca07b38 100644 (file)
@@ -126,6 +126,7 @@ add_library( ${BINARY_NAME}
     "../../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp"\r
     "../../../../../modules/juce_audio_devices/native/juce_ios_Audio.h"\r
     "../../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp"\r
+    "../../../../../modules/juce_audio_devices/native/juce_linux_Bela.cpp"\r
     "../../../../../modules/juce_audio_devices/native/juce_linux_JackAudio.cpp"\r
     "../../../../../modules/juce_audio_devices/native/juce_linux_Midi.cpp"\r
     "../../../../../modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp"\r
@@ -308,6 +309,7 @@ add_library( ${BINARY_NAME}
     "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h"\r
+    "../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_VST3Common.h"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_VST3Headers.h"\r
     "../../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp"\r
@@ -1080,6 +1082,8 @@ add_library( ${BINARY_NAME}
     "../../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"\r
     "../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp"\r
     "../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp"\r
+    "../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h"\r
     "../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp"\r
     "../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.h"\r
     "../../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp"\r
@@ -1364,6 +1368,7 @@ set_source_files_properties("../../../../../modules/juce_audio_devices/native/ju
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_ios_Audio.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_Bela.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_JackAudio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_linux_Midi.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
@@ -1546,6 +1551,7 @@ set_source_files_properties("../../../../../modules/juce_audio_processors/format
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3Common.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3Headers.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
@@ -2318,6 +2324,8 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/properties/j
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
+set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)\r
 set_source_files_properties("../../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp" PROPERTIES HEADER_FILE_ONLY TRUE)\r
index ae4b69c2dbf40f33c53b2617ef15ac0ac63905af..d438cc288d2c1f8a5e8af37a170914b643169b5a 100644 (file)
@@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
 \r
 android {\r
     compileSdkVersion 10\r
-    buildToolsVersion "27.0.0"\r
+    buildToolsVersion "27.0.3"\r
     externalNativeBuild {\r
         cmake {\r
             path "CMakeLists.txt"\r
index 9bf2c989a1f05e6dbc0304ce990a28d35df43f73..e37f33ec908692cb2be2eae7d2eb99abea688c8f 100644 (file)
@@ -306,7 +306,10 @@ public class JUCENetworkGraphicsDemo   extends Activity
 \r
         // Ensure that navigation/status bar visibility is correctly restored.\r
         for (int i = 0; i < viewHolder.getChildCount(); ++i)\r
-            ((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();\r
+        {\r
+            if (viewHolder.getChildAt (i) instanceof ComponentPeerView)\r
+                ((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();\r
+        }\r
     }\r
 \r
     @Override\r
@@ -888,19 +891,37 @@ public class JUCENetworkGraphicsDemo   extends Activity
 \r
             private class TreeObserver implements ViewTreeObserver.OnGlobalLayoutListener\r
             {\r
+                TreeObserver()\r
+                {\r
+                    keyboardShown = false;\r
+                }\r
+\r
                 @Override\r
                 public void onGlobalLayout()\r
                 {\r
                     Rect r = new Rect();\r
 \r
-                    view.getWindowVisibleDisplayFrame(r);\r
+                    ViewGroup parentView = (ViewGroup) getParent();\r
+\r
+                    if (parentView == null)\r
+                        return;\r
 \r
-                    int diff = view.getHeight() - (r.bottom - r.top);\r
+                    parentView.getWindowVisibleDisplayFrame (r);\r
+\r
+                    int diff = parentView.getHeight() - (r.bottom - r.top);\r
 \r
                     // Arbitrary threshold, surely keyboard would take more than 20 pix.\r
-                    if (diff < 20)\r
+                    if (diff < 20 && keyboardShown)\r
+                    {\r
+                        keyboardShown = false;\r
                         handleKeyboardHidden (view.host);\r
+                    }\r
+\r
+                    if (! keyboardShown && diff > 20)\r
+                        keyboardShown = true;\r
                 };\r
+\r
+                private boolean keyboardShown;\r
             };\r
 \r
             private ComponentPeerView view;\r
index 07b77dd931f3c186956af07d08e7ae7478ad1a88..651d63db63bdd2bf53a574bdde786ac927b14169 100644 (file)
@@ -1,15 +1,16 @@
 buildscript {\r
    repositories {\r
-       jcenter()\r
        google()\r
+       jcenter()\r
    }\r
    dependencies {\r
-       classpath 'com.android.tools.build:gradle:3.0.1'\r
+       classpath 'com.android.tools.build:gradle:3.1.1'\r
    }\r
 }\r
 \r
 allprojects {\r
    repositories {\r
+       google()\r
        jcenter()\r
    }\r
 }\r
index 6654a817a24092a7793c22f24c55a1c02dfbc7d4..d384d28fd88d3528bda61f4e6d2103d0ce17e8fe 100644 (file)
@@ -1 +1 @@
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
\ No newline at end of file
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
\ No newline at end of file
index f2520b44ca952b5e571f22aca9437ee3a845db21..68a37b87c1633a35f8e0e1c6ce9b236cfdea56e0 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
index 8f16c9936e5420e2291c6a017b6557668944832e..0694a1b51519a12dc75a73ff2bc54b2a88d13570 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
index 99fe149439920b2c53d090a5b75c346d921ca4cf..db60810df03d17000211cc93f29eccd5b84248a4 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
index f9bfb32b31993acab9fadeabcecc1e30a6d51c64..0801a22dccd86c4dfccfbc1a5f2012d8e6958d50 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
index 6e4d7425572ba7681acf8bf3865308d219307868..a7d5fe14aab2b068730a23196c8eb97c4f2b9d18 100644 (file)
  //#define JUCE_JACK 0\r
 #endif\r
 \r
+#ifndef    JUCE_BELA\r
+ //#define JUCE_BELA 0\r
+#endif\r
+\r
 #ifndef    JUCE_USE_ANDROID_OBOE\r
  //#define JUCE_USE_ANDROID_OBOE 0\r
 #endif\r
index 11d86451f2c67a36ab0b5c1bd2d7a7ebd3b0b27a..73cf0656d640bbec29c3b3722f753a1b8ee34ac1 100644 (file)
@@ -657,8 +657,7 @@ static const unsigned char temp_binary_data_0[] =
 const char* juce_icon_png = (const char*) temp_binary_data_0;\r
 \r
 \r
-const char* getNamedResource (const char*, int&) throw();\r
-const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw()\r
+const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) noexcept\r
 {\r
     unsigned int hash = 0;\r
     if (resourceNameUTF8 != 0)\r
@@ -672,7 +671,7 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw
     }\r
 \r
     numBytes = 0;\r
-    return 0;\r
+    return nullptr;\r
 }\r
 \r
 const char* namedResourceList[] =\r
@@ -680,4 +679,20 @@ const char* namedResourceList[] =
     "juce_icon_png"\r
 };\r
 \r
+const char* originalFilenames[] =\r
+{\r
+    "juce_icon.png"\r
+};\r
+\r
+const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8) noexcept\r
+{\r
+    for (unsigned int i = 0; i < (sizeof (namedResourceList) / sizeof (namedResourceList[0])); ++i)\r
+    {\r
+        if (namedResourceList[i] == resourceNameUTF8)\r
+            return originalFilenames[i];\r
+    }\r
+\r
+    return nullptr;\r
+}\r
+\r
 }\r
index 89e6cc9e730ca93f94ab7fd3677aed90feb38e2f..dd1ad0e91699bd430e857b497a79bdc4c9081645 100644 (file)
@@ -11,13 +11,20 @@ namespace BinaryData
     extern const char*   juce_icon_png;\r
     const int            juce_icon_pngSize = 45854;\r
 \r
+    // Number of elements in the namedResourceList and originalFileNames arrays.\r
+    const int namedResourceListSize = 1;\r
+\r
     // Points to the start of a list of resource names.\r
     extern const char* namedResourceList[];\r
 \r
-    // Number of elements in the namedResourceList array.\r
-    const int namedResourceListSize = 1;\r
+    // Points to the start of a list of resource filenames.\r
+    extern const char* originalFilenames[];\r
 \r
     // If you provide the name of one of the binary resource variables above, this function will\r
     // return the corresponding data and its size (or a null pointer if the name isn't found).\r
-    const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes) throw();\r
+    const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes) noexcept;\r
+\r
+    // If you provide the name of one of the binary resource variables above, this function will\r
+    // return the corresponding original, non-mangled filename (or a null pointer if the name isn't found).\r
+    const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8) noexcept;\r
 }\r
index 4db1c3379ad48456ddda5faa19d1b770f46d3cb6..3e9ef3e1f9c36f6720d99b0b63cfa4c9b7445d86 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 \r
 <JUCERPROJECT id="gWI5Ir" name="NetworkGraphicsDemo" projectType="guiapp" bundleIdentifier="com.juce.NetworkGraphicsDemo"\r
-              jucerVersion="5.3.0" displaySplashScreen="0" reportAppUsage="0"\r
+              jucerVersion="5.3.1" displaySplashScreen="0" reportAppUsage="0"\r
               companyName="ROLI Ltd." companyCopyright="ROLI Ltd.">\r
   <MAINGROUP id="OT9rJ2" name="NetworkGraphicsDemo">\r
     <GROUP id="{48D54E6E-37F4-B20A-E038-C63E4EDFD4D9}" name="Source">\r
index 4b176d7e1c667b09d09dd96d12fb25a98289caaf..d714b21567a0338241fea5343add983d61334c65 100644 (file)
@@ -35,7 +35,7 @@ ifeq ($(CONFIG),Debug)
     TARGET_ARCH := -march=native\r
   endif\r
 \r
-  JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.3.0 -DJUCE_APP_VERSION_HEX=0x50300 $(shell pkg-config --cflags freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)\r
+  JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.3.1 -DJUCE_APP_VERSION_HEX=0x50301 $(shell pkg-config --cflags freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)\r
   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
   JUCE_TARGET_APP := Projucer\r
 \r
@@ -56,7 +56,7 @@ ifeq ($(CONFIG),Release)
     TARGET_ARCH := -march=native\r
   endif\r
 \r
-  JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.3.0 -DJUCE_APP_VERSION_HEX=0x50300 $(shell pkg-config --cflags freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)\r
+  JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.3.1 -DJUCE_APP_VERSION_HEX=0x50301 $(shell pkg-config --cflags freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)\r
   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
   JUCE_TARGET_APP := Projucer\r
 \r
index f359ef4a8b00770ee98a75cb7285b3f54f6a9716..57fa3f929a7b74a0ca1c73b207d22f824f3f1a2f 100644 (file)
@@ -33,9 +33,9 @@
     <key>CFBundleSignature</key>\r
     <string>????</string>\r
     <key>CFBundleShortVersionString</key>\r
-    <string>5.3.0</string>\r
+    <string>5.3.1</string>\r
     <key>CFBundleVersion</key>\r
-    <string>5.3.0</string>\r
+    <string>5.3.1</string>\r
     <key>NSHumanReadableCopyright</key>\r
     <string>ROLI Ltd.</string>\r
     <key>NSHighResolutionCapable</key>\r
index dc08886581c2a290133afedc6ca2350559cba495..1aaba299c5dcdca2192f52f30cc64cff377365d7 100644 (file)
                0F8C000E5FF4A2DAC1FEF8EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ProjucerLookAndFeel.cpp"; 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; name = "jucer_ComponentTypeHandler.h"; path = "../../Source/ComponentEditor/Components/jucer_ComponentTypeHandler.h"; sourceTree = "SOURCE_ROOT"; };
+               124232706D1C8A3CA49E70CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PIPCreatorWindowComponent.h"; path = "../../Source/Application/Windows/jucer_PIPCreatorWindowComponent.h"; sourceTree = "SOURCE_ROOT"; };
                129F2DE0FEF154F8F8C7A74E = {isa = PBXFileReference; lastKnownFileType = file.jar; name = "gradle-wrapper.jar"; path = "../../Source/BinaryData/gradle/gradle-wrapper.jar"; sourceTree = "SOURCE_ROOT"; };
                133F1E428260C5ADDF496DF9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ComponentLayout.cpp"; path = "../../Source/ComponentEditor/jucer_ComponentLayout.cpp"; sourceTree = "SOURCE_ROOT"; };
                159DE1FEE2099398983CDDF0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ErrorList.h"; path = "../../Source/LiveBuildEngine/jucer_ErrorList.h"; sourceTree = "SOURCE_ROOT"; };
                4D5F0CA8D1273144681A1D48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_JucerTreeViewBase.cpp"; path = "../../Source/Utility/UI/jucer_JucerTreeViewBase.cpp"; sourceTree = "SOURCE_ROOT"; };
                4D698BF12BCD6B0896BCDF17 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_AutoUpdater.h"; path = "../../Source/Application/jucer_AutoUpdater.h"; sourceTree = "SOURCE_ROOT"; };
                4E671236FDBD5AD4699740C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_JucerCommandIDs.h"; path = "../../Source/ComponentEditor/UI/jucer_JucerCommandIDs.h"; sourceTree = "SOURCE_ROOT"; };
+               4ECF029E3A69BF42FED1503D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PIPAudioProcessorTemplate.h"; path = "../../Source/BinaryData/Templates/jucer_PIPAudioProcessorTemplate.h"; sourceTree = "SOURCE_ROOT"; };
                4F687965FBE86EAFDB3ACFEC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BinaryData.h; path = ../../JuceLibraryCode/BinaryData.h; sourceTree = "SOURCE_ROOT"; };
                4FF81FC167C924C47BD8C1C9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ProjectSaver.cpp"; path = "../../Source/ProjectSaving/jucer_ProjectSaver.cpp"; sourceTree = "SOURCE_ROOT"; };
                50498FF6EA3901CBD58223B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ObjectTypes.h"; path = "../../Source/ComponentEditor/jucer_ObjectTypes.h"; sourceTree = "SOURCE_ROOT"; };
                9F01BA9942D038EA8B5289A8 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QTKit.framework; path = System/Library/Frameworks/QTKit.framework; sourceTree = SDKROOT; };
                9F2D3E5FC10F7C3270908E97 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ButtonDocument.h"; path = "../../Source/ComponentEditor/Documents/jucer_ButtonDocument.h"; sourceTree = "SOURCE_ROOT"; };
                9F959ECF8CD9B7314AE604A9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_LabelHandler.h"; path = "../../Source/ComponentEditor/Components/jucer_LabelHandler.h"; sourceTree = "SOURCE_ROOT"; };
+               A081306A9E95CA114B81910F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_CompileEngineSettings.h"; 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; name = "jucer_ComponentLayoutPanel.h"; path = "../../Source/ComponentEditor/UI/jucer_ComponentLayoutPanel.h"; sourceTree = "SOURCE_ROOT"; };
                A160AEF56553A658E6EA6A8E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_MainTemplate_Window.cpp"; path = "../../Source/BinaryData/Templates/jucer_MainTemplate_Window.cpp"; sourceTree = "SOURCE_ROOT"; };
                E3BADF21095BC23DE2CB454F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectTreeItemBase.h"; path = "../../Source/Project/UI/Sidebar/jucer_ProjectTreeItemBase.h"; sourceTree = "SOURCE_ROOT"; };
                E468FDB5504C5D9315B2D04F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentDocument.h"; path = "../../Source/ComponentEditor/Documents/jucer_ComponentDocument.h"; sourceTree = "SOURCE_ROOT"; };
                E5D6C36496F5BC84D7213BE8 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+               E67999BF57B139E00207A374 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PIPTemplate.h"; path = "../../Source/BinaryData/Templates/jucer_PIPTemplate.h"; sourceTree = "SOURCE_ROOT"; };
                E96597BBC6A98255B51B94DC = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
                E983E6DDE3318B872EBE347F = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioKit.framework; path = System/Library/Frameworks/CoreAudioKit.framework; sourceTree = SDKROOT; };
                EAC1731150A7F79D59BAA0B6 = {isa = PBXFileReference; lastKnownFileType = file.svg; name = "export_visualStudio.svg"; path = "../../Source/BinaryData/Icons/export_visualStudio.svg"; sourceTree = "SOURCE_ROOT"; };
                                        D91E7F8FEF9290195D56782C,
                                        C736264708F3F68BA745BA29,
                                        EB2E723DC3DB150A8A644D08,
+                                       124232706D1C8A3CA49E70CD,
                                        DDC382008FFD9F9E0B2B0EDD,
                                        F7C74E934C954F6F1A3BE4F9,
                                        92926A4D3CC4BB2A9D35EB0B, ); name = Windows; sourceTree = "<group>"; };
                                        C607639897ED2538CBB860D0,
                                        023B92AC0340305762412E90,
                                        3F7C5B53347A487C7FBD2223,
-                                       3DC2ED15A9DFAAEF3D2ACDDF, ); name = Templates; sourceTree = "<group>"; };
+                                       4ECF029E3A69BF42FED1503D,
+                                       3DC2ED15A9DFAAEF3D2ACDDF,
+                                       E67999BF57B139E00207A374, ); name = Templates; sourceTree = "<group>"; };
                A9399733CAA07BDAB958242C = {isa = PBXGroup; children = (
                                        8CF70DA9AB4725126B9F55BE,
                                        F0F189518721D46C0F94FD56,
                                        A978DFE87D9BB5EFE5B3DAAC,
                                        D2FE76E4CF003856278343CC,
                                        BA186B51EE4884CD8E3F2741,
+                                       A081306A9E95CA114B81910F,
                                        ADD6A3CF5D7DE55E57E8E38B,
                                        A9954DC7F876A7006743ACB6,
                                        ADA538034910F52FDD2DC88D,
                                        "_DEBUG=1",
                                        "DEBUG=1",
                                        "JUCER_XCODE_MAC_F6D2F4CF=1",
-                                       "JUCE_APP_VERSION=5.3.0",
-                                       "JUCE_APP_VERSION_HEX=0x50300",
+                                       "JUCE_APP_VERSION=5.3.1",
+                                       "JUCE_APP_VERSION_HEX=0x50301",
                                        "JucePlugin_Build_VST=0",
                                        "JucePlugin_Build_VST3=0",
                                        "JucePlugin_Build_AU=0",
                                        "_NDEBUG=1",
                                        "NDEBUG=1",
                                        "JUCER_XCODE_MAC_F6D2F4CF=1",
-                                       "JUCE_APP_VERSION=5.3.0",
-                                       "JUCE_APP_VERSION_HEX=0x50300",
+                                       "JUCE_APP_VERSION=5.3.1",
+                                       "JUCE_APP_VERSION_HEX=0x50301",
                                        "JucePlugin_Build_VST=0",
                                        "JucePlugin_Build_VST3=0",
                                        "JucePlugin_Build_AU=0",
index 942676a8f1cfe610ce3b701a5312e5cfda1f4d1f..c442d2a2f8ace3d8fe7c5bd42015bb56964742db 100644 (file)
@@ -74,7 +74,7 @@
       <Optimization>Disabled</Optimization>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
       <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=5.3.0;JUCE_APP_VERSION_HEX=0x50300;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=5.3.1;JUCE_APP_VERSION_HEX=0x50301;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
       <PrecompiledHeader/>\r
     <ClCompile>\r
       <Optimization>Full</Optimization>\r
       <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=5.3.0;JUCE_APP_VERSION_HEX=0x50300;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=5.3.1;JUCE_APP_VERSION_HEX=0x50301;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
       <PrecompiledHeader/>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_EditorColourSchemeWindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_FloatingToolWindow.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_GlobalPathsWindowComponent.h"/>\r
+    <ClInclude Include="..\..\Source\Application\Windows\jucer_PIPCreatorWindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_SVGPathDataWindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_TranslationToolWindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_UTF8WindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_NewInlineComponentTemplate.h"/>\r
     <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentSimpleTemplate.h"/>\r
     <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentTemplate.h"/>\r
+    <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_PIPAudioProcessorTemplate.h"/>\r
+    <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_PIPTemplate.h"/>\r
     <ClInclude Include="..\..\Source\CodeEditor\jucer_DocumentEditorComponent.h"/>\r
     <ClInclude Include="..\..\Source\CodeEditor\jucer_ItemPreviewComponent.h"/>\r
     <ClInclude Include="..\..\Source\CodeEditor\jucer_LiveBuildCodeEditor.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineClient.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineDLL.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineServer.h"/>\r
+    <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineSettings.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CppHelpers.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_DiagnosticMessage.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_DownloadCompileEngineThread.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
index 54540be9110146438aa2e43f54d58aa889252916..695f3e93aa1550f6020c686262d2f5b305357d3d 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_GlobalPathsWindowComponent.h">\r
       <Filter>Projucer\Application\Windows</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\Source\Application\Windows\jucer_PIPCreatorWindowComponent.h">\r
+      <Filter>Projucer\Application\Windows</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_SVGPathDataWindowComponent.h">\r
       <Filter>Projucer\Application\Windows</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentTemplate.h">\r
       <Filter>Projucer\BinaryData\Templates</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_PIPAudioProcessorTemplate.h">\r
+      <Filter>Projucer\BinaryData\Templates</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_PIPTemplate.h">\r
+      <Filter>Projucer\BinaryData\Templates</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\Source\CodeEditor\jucer_DocumentEditorComponent.h">\r
       <Filter>Projucer\CodeEditor</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineServer.h">\r
       <Filter>Projucer\LiveBuildEngine</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineSettings.h">\r
+      <Filter>Projucer\LiveBuildEngine</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CppHelpers.h">\r
       <Filter>Projucer\LiveBuildEngine</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
index 1df27911692e627384598b8665476af5c54fea0b..a1f43a9bffdf16260135a31a9c10d59444f82bf7 100644 (file)
@@ -7,7 +7,7 @@
 #include <windows.h>\r
 \r
 VS_VERSION_INFO VERSIONINFO\r
-FILEVERSION  5,3,0,0\r
+FILEVERSION  5,3,1,0\r
 BEGIN\r
   BLOCK "StringFileInfo"\r
   BEGIN\r
@@ -16,9 +16,9 @@ BEGIN
       VALUE "CompanyName",  "ROLI Ltd.\0"\r
       VALUE "LegalCopyright",  "ROLI Ltd.\0"\r
       VALUE "FileDescription",  "Projucer\0"\r
-      VALUE "FileVersion",  "5.3.0\0"\r
+      VALUE "FileVersion",  "5.3.1\0"\r
       VALUE "ProductName",  "Projucer\0"\r
-      VALUE "ProductVersion",  "5.3.0\0"\r
+      VALUE "ProductVersion",  "5.3.1\0"\r
     END\r
   END\r
 \r
index 192d13c23bbfd4020f829c83e766c9089b3d2614..a57dea78776992b2fa5344b553cf01e27d52c6aa 100644 (file)
@@ -74,7 +74,7 @@
       <Optimization>Disabled</Optimization>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
       <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.3.0;JUCE_APP_VERSION_HEX=0x50300;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.3.1;JUCE_APP_VERSION_HEX=0x50301;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
       <PrecompiledHeader/>\r
     <ClCompile>\r
       <Optimization>Full</Optimization>\r
       <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.3.0;JUCE_APP_VERSION_HEX=0x50300;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.3.1;JUCE_APP_VERSION_HEX=0x50301;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
       <PrecompiledHeader/>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_EditorColourSchemeWindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_FloatingToolWindow.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_GlobalPathsWindowComponent.h"/>\r
+    <ClInclude Include="..\..\Source\Application\Windows\jucer_PIPCreatorWindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_SVGPathDataWindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_TranslationToolWindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_UTF8WindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_NewInlineComponentTemplate.h"/>\r
     <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentSimpleTemplate.h"/>\r
     <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentTemplate.h"/>\r
+    <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_PIPAudioProcessorTemplate.h"/>\r
+    <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_PIPTemplate.h"/>\r
     <ClInclude Include="..\..\Source\CodeEditor\jucer_DocumentEditorComponent.h"/>\r
     <ClInclude Include="..\..\Source\CodeEditor\jucer_ItemPreviewComponent.h"/>\r
     <ClInclude Include="..\..\Source\CodeEditor\jucer_LiveBuildCodeEditor.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineClient.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineDLL.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineServer.h"/>\r
+    <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineSettings.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CppHelpers.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_DiagnosticMessage.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_DownloadCompileEngineThread.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
index 21a5bd873b15dd040337ae252171bcd49f4efda4..22073c7afb1a3797dcd5be00de93e91d33d9701e 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_GlobalPathsWindowComponent.h">\r
       <Filter>Projucer\Application\Windows</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\Source\Application\Windows\jucer_PIPCreatorWindowComponent.h">\r
+      <Filter>Projucer\Application\Windows</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_SVGPathDataWindowComponent.h">\r
       <Filter>Projucer\Application\Windows</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentTemplate.h">\r
       <Filter>Projucer\BinaryData\Templates</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_PIPAudioProcessorTemplate.h">\r
+      <Filter>Projucer\BinaryData\Templates</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_PIPTemplate.h">\r
+      <Filter>Projucer\BinaryData\Templates</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\Source\CodeEditor\jucer_DocumentEditorComponent.h">\r
       <Filter>Projucer\CodeEditor</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineServer.h">\r
       <Filter>Projucer\LiveBuildEngine</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineSettings.h">\r
+      <Filter>Projucer\LiveBuildEngine</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CppHelpers.h">\r
       <Filter>Projucer\LiveBuildEngine</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
index 1df27911692e627384598b8665476af5c54fea0b..a1f43a9bffdf16260135a31a9c10d59444f82bf7 100644 (file)
@@ -7,7 +7,7 @@
 #include <windows.h>\r
 \r
 VS_VERSION_INFO VERSIONINFO\r
-FILEVERSION  5,3,0,0\r
+FILEVERSION  5,3,1,0\r
 BEGIN\r
   BLOCK "StringFileInfo"\r
   BEGIN\r
@@ -16,9 +16,9 @@ BEGIN
       VALUE "CompanyName",  "ROLI Ltd.\0"\r
       VALUE "LegalCopyright",  "ROLI Ltd.\0"\r
       VALUE "FileDescription",  "Projucer\0"\r
-      VALUE "FileVersion",  "5.3.0\0"\r
+      VALUE "FileVersion",  "5.3.1\0"\r
       VALUE "ProductName",  "Projucer\0"\r
-      VALUE "ProductVersion",  "5.3.0\0"\r
+      VALUE "ProductVersion",  "5.3.1\0"\r
     END\r
   END\r
 \r
index 5afda71705ab7809ae2841d063e27bdd076c8892..055a65ae002e22d8ca16b02f002494beb69b42e8 100644 (file)
@@ -74,7 +74,7 @@
       <Optimization>Disabled</Optimization>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
       <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.3.0;JUCE_APP_VERSION_HEX=0x50300;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.3.1;JUCE_APP_VERSION_HEX=0x50301;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
       <PrecompiledHeader/>\r
     <ClCompile>\r
       <Optimization>Full</Optimization>\r
       <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.3.0;JUCE_APP_VERSION_HEX=0x50300;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.3.1;JUCE_APP_VERSION_HEX=0x50301;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;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
       <RuntimeTypeInfo>true</RuntimeTypeInfo>\r
       <PrecompiledHeader/>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_EditorColourSchemeWindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_FloatingToolWindow.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_GlobalPathsWindowComponent.h"/>\r
+    <ClInclude Include="..\..\Source\Application\Windows\jucer_PIPCreatorWindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_SVGPathDataWindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_TranslationToolWindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_UTF8WindowComponent.h"/>\r
     <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_NewInlineComponentTemplate.h"/>\r
     <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentSimpleTemplate.h"/>\r
     <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentTemplate.h"/>\r
+    <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_PIPAudioProcessorTemplate.h"/>\r
+    <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_PIPTemplate.h"/>\r
     <ClInclude Include="..\..\Source\CodeEditor\jucer_DocumentEditorComponent.h"/>\r
     <ClInclude Include="..\..\Source\CodeEditor\jucer_ItemPreviewComponent.h"/>\r
     <ClInclude Include="..\..\Source\CodeEditor\jucer_LiveBuildCodeEditor.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineClient.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineDLL.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineServer.h"/>\r
+    <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineSettings.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CppHelpers.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_DiagnosticMessage.h"/>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_DownloadCompileEngineThread.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
index c189ff9c1165c3c3ff856e9545a227c0bf3e4b28..ecaaaa4f756baaa745cc660fbc55eede95381fd3 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_GlobalPathsWindowComponent.h">\r
       <Filter>Projucer\Application\Windows</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\Source\Application\Windows\jucer_PIPCreatorWindowComponent.h">\r
+      <Filter>Projucer\Application\Windows</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\Source\Application\Windows\jucer_SVGPathDataWindowComponent.h">\r
       <Filter>Projucer\Application\Windows</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentTemplate.h">\r
       <Filter>Projucer\BinaryData\Templates</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_PIPAudioProcessorTemplate.h">\r
+      <Filter>Projucer\BinaryData\Templates</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_PIPTemplate.h">\r
+      <Filter>Projucer\BinaryData\Templates</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\Source\CodeEditor\jucer_DocumentEditorComponent.h">\r
       <Filter>Projucer\CodeEditor</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineServer.h">\r
       <Filter>Projucer\LiveBuildEngine</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineSettings.h">\r
+      <Filter>Projucer\LiveBuildEngine</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_CppHelpers.h">\r
       <Filter>Projucer\LiveBuildEngine</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
index 1df27911692e627384598b8665476af5c54fea0b..a1f43a9bffdf16260135a31a9c10d59444f82bf7 100644 (file)
@@ -7,7 +7,7 @@
 #include <windows.h>\r
 \r
 VS_VERSION_INFO VERSIONINFO\r
-FILEVERSION  5,3,0,0\r
+FILEVERSION  5,3,1,0\r
 BEGIN\r
   BLOCK "StringFileInfo"\r
   BEGIN\r
@@ -16,9 +16,9 @@ BEGIN
       VALUE "CompanyName",  "ROLI Ltd.\0"\r
       VALUE "LegalCopyright",  "ROLI Ltd.\0"\r
       VALUE "FileDescription",  "Projucer\0"\r
-      VALUE "FileVersion",  "5.3.0\0"\r
+      VALUE "FileVersion",  "5.3.1\0"\r
       VALUE "ProductName",  "Projucer\0"\r
-      VALUE "ProductVersion",  "5.3.0\0"\r
+      VALUE "ProductVersion",  "5.3.1\0"\r
     END\r
   END\r
 \r
index b596ae62bbd6a2aac7c241cbecac3cbbf5059fba..a143ceafbf602c715570c60bd5ff0eb309fcb3bc 100644 (file)
@@ -7051,8 +7051,120 @@ static const unsigned char temp_binary_data_51[] =
 \r
 const char* jucer_OpenGLComponentTemplate_h = (const char*) temp_binary_data_51;\r
 \r
-//================== jucer_PIPMain.cpp ==================\r
+//================== jucer_PIPAudioProcessorTemplate.h ==================\r
 static const unsigned char temp_binary_data_52[] =\r
+"class %%class_name%%  : public AudioProcessor\r\n"\r
+"{\r\n"\r
+"public:\r\n"\r
+"    //==============================================================================\r\n"\r
+"    %%class_name%%()\r\n"\r
+"        : AudioProcessor (BusesProperties().withInput  (\"Input\",  AudioChannelSet::stereo())\r\n"\r
+"                                           .withOutput (\"Output\", AudioChannelSet::stereo()))\r\n"\r
+"    {\r\n"\r
+"    }\r\n"\r
+"\r\n"\r
+"    ~%%class_name%%()\r\n"\r
+"    {\r\n"\r
+"    }\r\n"\r
+"\r\n"\r
+"    //==============================================================================\r\n"\r
+"    void prepareToPlay (double, int) override\r\n"\r
+"    {\r\n"\r
+"        // Use this method as the place to do any pre-playback\r\n"\r
+"        // initialisation that you need..\r\n"\r
+"    }\r\n"\r
+"\r\n"\r
+"    void releaseResources() override\r\n"\r
+"    {\r\n"\r
+"        // When playback stops, you can use this as an opportunity to free up any\r\n"\r
+"        // spare memory, etc.\r\n"\r
+"    }\r\n"\r
+"\r\n"\r
+"    void processBlock (AudioBuffer<float>& buffer, MidiBuffer&) override\r\n"\r
+"    {\r\n"\r
+"        ScopedNoDenormals noDenormals;\r\n"\r
+"        auto totalNumInputChannels  = getTotalNumInputChannels();\r\n"\r
+"        auto totalNumOutputChannels = getTotalNumOutputChannels();\r\n"\r
+"\r\n"\r
+"        // In case we have more outputs than inputs, this code clears any output\r\n"\r
+"        // channels that didn't contain input data, (because these aren't\r\n"\r
+"        // guaranteed to be empty - they may contain garbage).\r\n"\r
+"        // This is here to avoid people getting screaming feedback\r\n"\r
+"        // when they first compile a plugin, but obviously you don't need to keep\r\n"\r
+"        // this code if your algorithm always overwrites all the output channels.\r\n"\r
+"        for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)\r\n"\r
+"            buffer.clear (i, 0, buffer.getNumSamples());\r\n"\r
+"\r\n"\r
+"        // This is the place where you'd normally do the guts of your plugin's\r\n"\r
+"        // audio processing...\r\n"\r
+"        // Make sure to reset the state if your inner loop is processing\r\n"\r
+"        // the samples and the outer loop is handling the channels.\r\n"\r
+"        // Alternatively, you can process the samples with the channels\r\n"\r
+"        // interleaved by keeping the same state.\r\n"\r
+"        for (int channel = 0; channel < totalNumInputChannels; ++channel)\r\n"\r
+"        {\r\n"\r
+"            auto* channelData = buffer.getWritePointer (channel);\r\n"\r
+"\r\n"\r
+"            // ..do something to the data...\r\n"\r
+"        }\r\n"\r
+"    }\r\n"\r
+"\r\n"\r
+"    //==============================================================================\r\n"\r
+"    AudioProcessorEditor* createEditor() override          { return nullptr; }\r\n"\r
+"    bool hasEditor() const override                        { return false;   }\r\n"\r
+"\r\n"\r
+"    //==============================================================================\r\n"\r
+"    const String getName() const override                  { return \"%%name%%\"; }\r\n"\r
+"    bool acceptsMidi() const override                      { return false; }\r\n"\r
+"    bool producesMidi() const override                     { return false; }\r\n"\r
+"    double getTailLengthSeconds() const override           { return 0; }\r\n"\r
+"\r\n"\r
+"    //==============================================================================\r\n"\r
+"    int getNumPrograms() override                          { return 1; }\r\n"\r
+"    int getCurrentProgram() override                       { return 0; }\r\n"\r
+"    void setCurrentProgram (int) override                  {}\r\n"\r
+"    const String getProgramName (int) override             { return {}; }\r\n"\r
+"    void changeProgramName (int, const String&) override   {}\r\n"\r
+"\r\n"\r
+"    //==============================================================================\r\n"\r
+"    void getStateInformation (MemoryBlock& destData) override\r\n"\r
+"    {\r\n"\r
+"        // You should use this method to store your parameters in the memory block.\r\n"\r
+"        // You could do that either as raw data, or use the XML or ValueTree classes\r\n"\r
+"        // as intermediaries to make it easy to save and load complex data.\r\n"\r
+"    }\r\n"\r
+"\r\n"\r
+"    void setStateInformation (const void* data, int sizeInBytes) override\r\n"\r
+"    {\r\n"\r
+"        // You should use this method to restore your parameters from this memory block,\r\n"\r
+"        // whose contents will have been created by the getStateInformation() call.\r\n"\r
+"    }\r\n"\r
+"\r\n"\r
+"    //==============================================================================\r\n"\r
+"    bool isBusesLayoutSupported (const BusesLayout& layouts) const override\r\n"\r
+"    {\r\n"\r
+"        // This is the place where you check if the layout is supported.\r\n"\r
+"        // In this template code we only support mono or stereo.\r\n"\r
+"        if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono()\r\n"\r
+"            && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())\r\n"\r
+"            return false;\r\n"\r
+"\r\n"\r
+"        // This checks if the input layout matches the output layout\r\n"\r
+"        if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())\r\n"\r
+"            return false;\r\n"\r
+"\r\n"\r
+"        return true;\r\n"\r
+"    }\r\n"\r
+"\r\n"\r
+"private:\r\n"\r
+"    //==============================================================================\r\n"\r
+"    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%class_name%%)\r\n"\r
+"};\r\n";\r
+\r
+const char* jucer_PIPAudioProcessorTemplate_h = (const char*) temp_binary_data_52;\r
+\r
+//================== jucer_PIPMain.cpp ==================\r
+static const unsigned char temp_binary_data_53[] =\r
 "/*\r\n"\r
 "  ==============================================================================\r\n"\r
 "\r\n"\r
@@ -7081,10 +7193,11 @@ static const unsigned char temp_binary_data_52[] =
 "    class MainWindow    : public DocumentWindow\r\n"\r
 "    {\r\n"\r
 "    public:\r\n"\r
-"        MainWindow (const String& name, Component* c)  : DocumentWindow (name,\r\n"\r
-"                                                                         Desktop::getInstance().getDefaultLookAndFeel()\r\n"\r
-"                                                                                               .findColour (ResizableWindow::backgroundColourId),\r\n"\r
-"                                                                         DocumentWindow::allButtons)\r\n"\r
+"        MainWindow (const String& name, Component* c, JUCEApplication& a)\r\n"\r
+"            : DocumentWindow (name, Desktop::getInstance().getDefaultLookAndFeel()\r\n"\r
+"                                                          .findColour (ResizableWindow::backgroundColourId),\r\n"\r
+"                              DocumentWindow::allButtons),\r\n"\r
+"              app (a)\r\n"\r
 "        {\r\n"\r
 "            setUsingNativeTitleBar (true);\r\n"\r
 "            setContentOwned (c, true);\r\n"\r
@@ -7102,10 +7215,13 @@ static const unsigned char temp_binary_data_52[] =
 "\r\n"\r
 "        void closeButtonPressed() override\r\n"\r
 "        {\r\n"\r
-"            JUCEApplication::getInstance()->systemRequestedQuit();\r\n"\r
+"            app.systemRequestedQuit();\r\n"\r
 "        }\r\n"\r
 "\r\n"\r
 "    private:\r\n"\r
+"        JUCEApplication& app;\r\n"\r
+"\r\n"\r
+"        //==============================================================================\r\n"\r
 "        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)\r\n"\r
 "    };\r\n"\r
 "    ScopedPointer<MainWindow> mainWindow;\r\n"\r
@@ -7126,10 +7242,32 @@ static const unsigned char temp_binary_data_52[] =
 "%%console_begin%%\r\n"\r
 "%%console_end%%\r\n";\r
 \r
-const char* jucer_PIPMain_cpp = (const char*) temp_binary_data_52;\r
+const char* jucer_PIPMain_cpp = (const char*) temp_binary_data_53;\r
+\r
+//================== jucer_PIPTemplate.h ==================\r
+static const unsigned char temp_binary_data_54[] =\r
+"/*******************************************************************************\r\n"\r
+" The block below describes the properties of this PIP. A PIP is a short snippet\r\n"\r
+" of code that can be read by the Projucer and used to generate a JUCE project.\r\n"\r
+"\r\n"\r
+" BEGIN_JUCE_PIP_METADATA\r\n"\r
+"\r\n"\r
+"%%pip_metadata%%\r\n"\r
+"\r\n"\r
+" END_JUCE_PIP_METADATA\r\n"\r
+"\r\n"\r
+"*******************************************************************************/\r\n"\r
+"\r\n"\r
+"#pragma once\r\n"\r
+"\r\n"\r
+"\r\n"\r
+"//==============================================================================\r\n"\r
+"%%pip_code%%\r\n";\r
+\r
+const char* jucer_PIPTemplate_h = (const char*) temp_binary_data_54;\r
 \r
 //================== colourscheme_dark.xml ==================\r
-static const unsigned char temp_binary_data_53[] =\r
+static const unsigned char temp_binary_data_55[] =\r
 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"\r
 "\r\n"\r
 "<COLOUR_SCHEME font=\"&lt;Monospaced&gt;; 13.0\">\r\n"\r
@@ -7154,10 +7292,10 @@ static const unsigned char temp_binary_data_53[] =
 "  <COLOUR name=\"Error\" colour=\"FFE60000\"/>\r\n"\r
 "</COLOUR_SCHEME>\r\n";\r
 \r
-const char* colourscheme_dark_xml = (const char*) temp_binary_data_53;\r
+const char* colourscheme_dark_xml = (const char*) temp_binary_data_55;\r
 \r
 //================== colourscheme_light.xml ==================\r
-static const unsigned char temp_binary_data_54[] =\r
+static const unsigned char temp_binary_data_56[] =\r
 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"\r
 "\r\n"\r
 "<COLOUR_SCHEME font=\"&lt;Monospaced&gt;; 13.0\">\r\n"\r
@@ -7182,16 +7320,16 @@ static const unsigned char temp_binary_data_54[] =
 "  <COLOUR name=\"Error\" colour=\"ffcc0000\"/>\r\n"\r
 "</COLOUR_SCHEME>\r\n";\r
 \r
-const char* colourscheme_light_xml = (const char*) temp_binary_data_54;\r
+const char* colourscheme_light_xml = (const char*) temp_binary_data_56;\r
 \r
 //================== nothingtoseehere.txt ==================\r
-static const unsigned char temp_binary_data_55[] =\r
+static const unsigned char temp_binary_data_57[] =\r
 "VUEtMTk3NTkzMTgtNA==";\r
 \r
-const char* nothingtoseehere_txt = (const char*) temp_binary_data_55;\r
+const char* nothingtoseehere_txt = (const char*) temp_binary_data_57;\r
 \r
 //================== offlinepage.html ==================\r
-static const unsigned char temp_binary_data_56[] =\r
+static const unsigned char temp_binary_data_58[] =\r
 "<html>\n"\r
 "  <head>\n"\r
 "    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=11\">\n"\r
@@ -7235,10 +7373,10 @@ static const unsigned char temp_binary_data_56[] =
 "  </body>\n"\r
 "</html>";\r
 \r
-const char* offlinepage_html = (const char*) temp_binary_data_56;\r
+const char* offlinepage_html = (const char*) temp_binary_data_58;\r
 \r
 //================== projucer_EULA.txt ==================\r
-static const unsigned char temp_binary_data_57[] =\r
+static const unsigned char temp_binary_data_59[] =\r
 "\r\n"\r
 "IMPORTANT NOTICE: PLEASE READ CAREFULLY BEFORE INSTALLING THE SOFTWARE:\r\n"\r
 "\r\n"\r
@@ -7402,10 +7540,10 @@ static const unsigned char temp_binary_data_57[] =
 "\r\n"\r
 "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";\r
 \r
-const char* projucer_EULA_txt = (const char*) temp_binary_data_57;\r
+const char* projucer_EULA_txt = (const char*) temp_binary_data_59;\r
 \r
 //================== RecentFilesMenuTemplate.nib ==================\r
-static const unsigned char temp_binary_data_58[] =\r
+static const unsigned char temp_binary_data_60[] =\r
 { 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,\r
 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,\r
 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,\r
@@ -7442,11 +7580,10 @@ static const unsigned char temp_binary_data_58[] =
 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,\r
 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 };\r
 \r
-const char* RecentFilesMenuTemplate_nib = (const char*) temp_binary_data_58;\r
+const char* RecentFilesMenuTemplate_nib = (const char*) temp_binary_data_60;\r
 \r
 \r
-const char* getNamedResource (const char*, int&) throw();\r
-const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw()\r
+const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) noexcept\r
 {\r
     unsigned int hash = 0;\r
     if (resourceNameUTF8 != 0)\r
@@ -7507,7 +7644,9 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw
         case 0x6bdeb129:  numBytes = 2174; return jucer_OpenGLComponentSimpleTemplate_h;\r
         case 0x7fbac252:  numBytes = 1665; return jucer_OpenGLComponentTemplate_cpp;\r
         case 0x491fa0d7:  numBytes = 1263; return jucer_OpenGLComponentTemplate_h;\r
-        case 0xf4ca9e9a:  numBytes = 2446; return jucer_PIPMain_cpp;\r
+        case 0xbc050edc:  numBytes = 4926; return jucer_PIPAudioProcessorTemplate_h;\r
+        case 0xf4ca9e9a:  numBytes = 2443; return jucer_PIPMain_cpp;\r
+        case 0x0b16e320:  numBytes = 517; return jucer_PIPTemplate_h;\r
         case 0x763d39dc:  numBytes = 1050; return colourscheme_dark_xml;\r
         case 0xe8b08520:  numBytes = 1050; return colourscheme_light_xml;\r
         case 0x938e96ec:  numBytes = 20; return nothingtoseehere_txt;\r
@@ -7518,7 +7657,7 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw
     }\r
 \r
     numBytes = 0;\r
-    return 0;\r
+    return nullptr;\r
 }\r
 \r
 const char* namedResourceList[] =\r
@@ -7575,7 +7714,9 @@ const char* namedResourceList[] =
     "jucer_OpenGLComponentSimpleTemplate_h",\r
     "jucer_OpenGLComponentTemplate_cpp",\r
     "jucer_OpenGLComponentTemplate_h",\r
+    "jucer_PIPAudioProcessorTemplate_h",\r
     "jucer_PIPMain_cpp",\r
+    "jucer_PIPTemplate_h",\r
     "colourscheme_dark_xml",\r
     "colourscheme_light_xml",\r
     "nothingtoseehere_txt",\r
@@ -7584,4 +7725,80 @@ const char* namedResourceList[] =
     "RecentFilesMenuTemplate_nib"\r
 };\r
 \r
+const char* originalFilenames[] =\r
+{\r
+    "gradle-wrapper.jar",\r
+    "gradlew",\r
+    "gradlew.bat",\r
+    "LICENSE",\r
+    "background_logo.svg",\r
+    "export_android.svg",\r
+    "export_clion.svg",\r
+    "export_codeBlocks.svg",\r
+    "export_linux.svg",\r
+    "export_visualStudio.svg",\r
+    "export_xcode.svg",\r
+    "huckleberry_icon.svg",\r
+    "juce-logo-with-text.svg",\r
+    "juce_icon.png",\r
+    "wizard_AnimatedApp.svg",\r
+    "wizard_AudioApp.svg",\r
+    "wizard_AudioPlugin.svg",\r
+    "wizard_ConsoleApp.svg",\r
+    "wizard_DLL.svg",\r
+    "wizard_GUI.svg",\r
+    "wizard_Highlight.svg",\r
+    "wizard_Openfile.svg",\r
+    "wizard_OpenGL.svg",\r
+    "wizard_StaticLibrary.svg",\r
+    "jucer_AnimatedComponentSimpleTemplate.h",\r
+    "jucer_AnimatedComponentTemplate.cpp",\r
+    "jucer_AnimatedComponentTemplate.h",\r
+    "jucer_AudioComponentSimpleTemplate.h",\r
+    "jucer_AudioComponentTemplate.cpp",\r
+    "jucer_AudioComponentTemplate.h",\r
+    "jucer_AudioPluginEditorTemplate.cpp",\r
+    "jucer_AudioPluginEditorTemplate.h",\r
+    "jucer_AudioPluginFilterTemplate.cpp",\r
+    "jucer_AudioPluginFilterTemplate.h",\r
+    "jucer_ComponentTemplate.cpp",\r
+    "jucer_ComponentTemplate.h",\r
+    "jucer_ContentCompSimpleTemplate.h",\r
+    "jucer_ContentCompTemplate.cpp",\r
+    "jucer_ContentCompTemplate.h",\r
+    "jucer_InlineComponentTemplate.h",\r
+    "jucer_MainConsoleAppTemplate.cpp",\r
+    "jucer_MainTemplate_NoWindow.cpp",\r
+    "jucer_MainTemplate_SimpleWindow.cpp",\r
+    "jucer_MainTemplate_Window.cpp",\r
+    "jucer_NewComponentTemplate.cpp",\r
+    "jucer_NewComponentTemplate.h",\r
+    "jucer_NewCppFileTemplate.cpp",\r
+    "jucer_NewCppFileTemplate.h",\r
+    "jucer_NewInlineComponentTemplate.h",\r
+    "jucer_OpenGLComponentSimpleTemplate.h",\r
+    "jucer_OpenGLComponentTemplate.cpp",\r
+    "jucer_OpenGLComponentTemplate.h",\r
+    "jucer_PIPAudioProcessorTemplate.h",\r
+    "jucer_PIPMain.cpp",\r
+    "jucer_PIPTemplate.h",\r
+    "colourscheme_dark.xml",\r
+    "colourscheme_light.xml",\r
+    "nothingtoseehere.txt",\r
+    "offlinepage.html",\r
+    "projucer_EULA.txt",\r
+    "RecentFilesMenuTemplate.nib"\r
+};\r
+\r
+const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8) noexcept\r
+{\r
+    for (unsigned int i = 0; i < (sizeof (namedResourceList) / sizeof (namedResourceList[0])); ++i)\r
+    {\r
+        if (namedResourceList[i] == resourceNameUTF8)\r
+            return originalFilenames[i];\r
+    }\r
+\r
+    return nullptr;\r
+}\r
+\r
 }\r
index 5a86497df4f73b32af31693c33c62f880ca61ca8..4c0adcd9b3960138f3f35947bdbb955189c72cd0 100644 (file)
@@ -164,8 +164,14 @@ namespace BinaryData
     extern const char*   jucer_OpenGLComponentTemplate_h;\r
     const int            jucer_OpenGLComponentTemplate_hSize = 1263;\r
 \r
+    extern const char*   jucer_PIPAudioProcessorTemplate_h;\r
+    const int            jucer_PIPAudioProcessorTemplate_hSize = 4926;\r
+\r
     extern const char*   jucer_PIPMain_cpp;\r
-    const int            jucer_PIPMain_cppSize = 2446;\r
+    const int            jucer_PIPMain_cppSize = 2443;\r
+\r
+    extern const char*   jucer_PIPTemplate_h;\r
+    const int            jucer_PIPTemplate_hSize = 517;\r
 \r
     extern const char*   colourscheme_dark_xml;\r
     const int            colourscheme_dark_xmlSize = 1050;\r
@@ -185,13 +191,20 @@ namespace BinaryData
     extern const char*   RecentFilesMenuTemplate_nib;\r
     const int            RecentFilesMenuTemplate_nibSize = 2842;\r
 \r
+    // Number of elements in the namedResourceList and originalFileNames arrays.\r
+    const int namedResourceListSize = 61;\r
+\r
     // Points to the start of a list of resource names.\r
     extern const char* namedResourceList[];\r
 \r
-    // Number of elements in the namedResourceList array.\r
-    const int namedResourceListSize = 59;\r
+    // Points to the start of a list of resource filenames.\r
+    extern const char* originalFilenames[];\r
 \r
     // If you provide the name of one of the binary resource variables above, this function will\r
     // return the corresponding data and its size (or a null pointer if the name isn't found).\r
-    const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes) throw();\r
+    const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes) noexcept;\r
+\r
+    // If you provide the name of one of the binary resource variables above, this function will\r
+    // return the corresponding original, non-mangled filename (or a null pointer if the name isn't found).\r
+    const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8) noexcept;\r
 }\r
index 1788d55fa7c79ca50a0db34233e88e39324ad57c..e7fa6cc221f5335bae7e443fec4c5121eeb1b24e 100644 (file)
@@ -35,7 +35,7 @@
 namespace ProjectInfo\r
 {\r
     const char* const  projectName    = "Projucer";\r
-    const char* const  versionString  = "5.3.0";\r
-    const int          versionNumber  = 0x50300;\r
+    const char* const  versionString  = "5.3.1";\r
+    const int          versionNumber  = 0x50301;\r
 }\r
 #endif\r
index 14c07a111cc1a4b1a431c637feabd50bcdd6fc94..b1c11a2d652d85cdd94dc3eae482a24d53af3805 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 \r
 <JUCERPROJECT id="M70qfTRRk" name="Projucer" projectType="guiapp" juceFolder="../../juce"\r
-              jucerVersion="5.3.0" version="5.3.0" bundleIdentifier="com.juce.theprojucer"\r
+              jucerVersion="5.3.1" version="5.3.1" bundleIdentifier="com.juce.theprojucer"\r
               defines="" splashScreenColour="Dark" displaySplashScreen="0"\r
               reportAppUsage="0" companyName="ROLI Ltd." companyCopyright="ROLI Ltd."\r
               cppLanguageStandard="11">\r
               file="Source/Application/Windows/jucer_FloatingToolWindow.h"/>\r
         <FILE id="dqgeFF" name="jucer_GlobalPathsWindowComponent.h" compile="0"\r
               resource="0" file="Source/Application/Windows/jucer_GlobalPathsWindowComponent.h"/>\r
+        <FILE id="snVgLV" name="jucer_PIPCreatorWindowComponent.h" compile="0"\r
+              resource="0" file="Source/Application/Windows/jucer_PIPCreatorWindowComponent.h"/>\r
         <FILE id="RyqPBc" name="jucer_SVGPathDataWindowComponent.h" compile="0"\r
               resource="0" file="Source/Application/Windows/jucer_SVGPathDataWindowComponent.h"/>\r
         <FILE id="ideTas" name="jucer_TranslationToolWindowComponent.h" compile="0"\r
               resource="1" file="Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.cpp"/>\r
         <FILE id="Edyh5d" name="jucer_OpenGLComponentTemplate.h" compile="0"\r
               resource="1" file="Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.h"/>\r
+        <FILE id="BVHe2G" name="jucer_PIPAudioProcessorTemplate.h" compile="0"\r
+              resource="1" file="Source/BinaryData/Templates/jucer_PIPAudioProcessorTemplate.h"/>\r
         <FILE id="aUkNL5" name="jucer_PIPMain.cpp" compile="0" resource="1"\r
               file="Source/BinaryData/Templates/jucer_PIPMain.cpp"/>\r
+        <FILE id="WqDCf0" name="jucer_PIPTemplate.h" compile="0" resource="1"\r
+              file="Source/BinaryData/Templates/jucer_PIPTemplate.h"/>\r
       </GROUP>\r
       <FILE id="oXM3fR" name="colourscheme_dark.xml" compile="0" resource="1"\r
             file="Source/BinaryData/colourscheme_dark.xml"/>\r
             resource="0" file="Source/LiveBuildEngine/jucer_CompileEngineServer.cpp"/>\r
       <FILE id="RraER0" name="jucer_CompileEngineServer.h" compile="0" resource="0"\r
             file="Source/LiveBuildEngine/jucer_CompileEngineServer.h"/>\r
+      <FILE id="hKqvP1" name="jucer_CompileEngineSettings.h" compile="0"\r
+            resource="0" file="Source/LiveBuildEngine/jucer_CompileEngineSettings.h"/>\r
       <FILE id="YlfzAt" name="jucer_CppHelpers.h" compile="0" resource="0"\r
             file="Source/LiveBuildEngine/jucer_CppHelpers.h"/>\r
       <FILE id="yW3rHq" name="jucer_DiagnosticMessage.h" compile="0" resource="0"\r
index 8a9e77a791e97166517d287b373d54393a0e3963..3e784c6e08f0607538f8144b2974db822a9aef67 100644 (file)
@@ -58,7 +58,7 @@ public:
         addAndMakeVisible (privacyPolicyLink);\r
         privacyPolicyLink.setButtonText ("Privacy Policy");\r
         privacyPolicyLink.setFont (Font (14.0f), false);\r
-        privacyPolicyLink.setURL (URL ("https://juce.com/privacy-policy"));\r
+        privacyPolicyLink.setURL (URL ("https://juce.com/juce-5-privacy-policy"));\r
 \r
         addAndMakeVisible (okButton);\r
 \r
diff --git a/extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h b/extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h
new file mode 100644 (file)
index 0000000..184c04b
--- /dev/null
@@ -0,0 +1,333 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#pragma once\r
+\r
+//==============================================================================\r
+static String getWidthLimitedStringFromVarArray (const var& varArray) noexcept\r
+{\r
+    if (! varArray.isArray())\r
+        return {};\r
+\r
+    int numLines = 1;\r
+    const int lineWidth = 100;\r
+    const String indent ("                    ");\r
+\r
+    String str;\r
+    if (auto* arr = varArray.getArray())\r
+    {\r
+        for (auto& v : *arr)\r
+        {\r
+            if ((str.length() + v.toString().length()) > (lineWidth * numLines))\r
+            {\r
+                str += newLine;\r
+                str += indent;\r
+\r
+                ++numLines;\r
+            }\r
+\r
+            str += v.toString() + (arr->indexOf (v) != arr->size() - 1 ? ", " : "");\r
+        }\r
+    }\r
+\r
+    return str;\r
+}\r
+\r
+//==============================================================================\r
+class PIPCreatorWindowComponent    : public Component,\r
+                                     private ValueTree::Listener\r
+{\r
+public:\r
+    PIPCreatorWindowComponent()\r
+    {\r
+        setLookAndFeel (lf = new PIPCreatorLookAndFeel());\r
+\r
+        addAndMakeVisible (propertyViewport);\r
+        propertyViewport.setViewedComponent (&propertyGroup, false);\r
+        buildProps();\r
+\r
+        addAndMakeVisible (createButton);\r
+        createButton.onClick = [this]\r
+        {\r
+            FileChooser fc ("Save PIP File",\r
+                            File::getSpecialLocation (File::SpecialLocationType::userDesktopDirectory)\r
+                                 .getChildFile (nameValue.get().toString() + ".h"));\r
+\r
+            fc.browseForFileToSave (true);\r
+\r
+            createPIPFile (fc.getResult());\r
+        };\r
+\r
+        pipTree.addListener (this);\r
+    }\r
+\r
+    ~PIPCreatorWindowComponent()\r
+    {\r
+        setLookAndFeel (nullptr);\r
+    }\r
+\r
+    void resized() override\r
+    {\r
+        auto bounds = getLocalBounds();\r
+\r
+        createButton.setBounds (bounds.removeFromBottom (50).reduced (100, 10));\r
+\r
+        propertyGroup.updateSize (0, 0, getWidth() - propertyViewport.getScrollBarThickness());\r
+        propertyViewport.setBounds (bounds);\r
+    }\r
+\r
+private:\r
+    //==============================================================================\r
+    struct PIPCreatorLookAndFeel    : public ProjucerLookAndFeel\r
+    {\r
+        PIPCreatorLookAndFeel()    {}\r
+\r
+        Rectangle<int> getPropertyComponentContentPosition (PropertyComponent& component)\r
+        {\r
+            auto textW = jmin (200, component.getWidth() / 3);\r
+            return { textW, 0, component.getWidth() - textW, component.getHeight() - 1 };\r
+        }\r
+    };\r
+\r
+    //==============================================================================\r
+    void buildProps()\r
+    {\r
+        PropertyListBuilder builder;\r
+\r
+        builder.add (new TextPropertyComponent (nameValue, "Name", 256, false),\r
+                     "The name of your JUCE project.");\r
+        builder.add (new TextPropertyComponent (versionValue, "Version", 16, false),\r
+                     "This will be used for the \"Project Version\" field in the Projucer.");\r
+        builder.add (new TextPropertyComponent (vendorValue, "Vendor", 2048, false),\r
+                     "This will be used for the \"Company Name\" field in the Projucer.");\r
+        builder.add (new TextPropertyComponent (websiteValue, "Website", 2048, false),\r
+                     "This will be used for the \"Company Website\" field in the Projucer");\r
+        builder.add (new TextPropertyComponent (descriptionValue, "Description", 2048, true),\r
+                     "A short description of your JUCE project.");\r
+\r
+        {\r
+            Array<var> moduleVars;\r
+            for (auto& m : getJUCEModules())\r
+                moduleVars.add (m);\r
+\r
+            builder.add (new MultiChoicePropertyComponent (dependenciesValue, "Dependencies",\r
+                                                           getJUCEModules(), moduleVars),\r
+                         "The JUCE modules that should be added to your project.");\r
+        }\r
+\r
+        {\r
+            Array<var> exporterVars;\r
+            for (auto& e : ProjectExporter::getExporterValueTreeNames())\r
+                exporterVars.add (e.toLowerCase());\r
+\r
+            builder.add (new MultiChoicePropertyComponent (exportersValue, "Exporters",\r
+                                                           ProjectExporter::getExporterNames(), exporterVars),\r
+                         "The exporters that should be added to your project.");\r
+        }\r
+\r
+        builder.add (new TextPropertyComponent (moduleFlagsValue, "Module Flags", 2048, true),\r
+                     "Use this to set one, or many, of the JUCE module flags");\r
+        builder.add (new TextPropertyComponent (definesValue, "Defines", 2048, true),\r
+                     "This sets some global preprocessor definitions for your project. Used to populate the \"Preprocessor Definitions\" field in the Projucer.");\r
+        builder.add (new ChoicePropertyComponent (typeValue, "Type",\r
+                                                  { "Component", "Plugin",         "Console Application" },\r
+                                                  { "Component", "AudioProcessor", "Console" }),\r
+                     "The project type.");\r
+\r
+        builder.add (new TextPropertyComponent (mainClassValue, "Main Class", 2048, false),\r
+                     "The name of the main class that should be instantiated. "\r
+                     "There can only be one main class and it must have a default constructor. "\r
+                     "Depending on the type, this may need to inherit from a specific JUCE class");\r
+\r
+        builder.add (new ChoicePropertyComponent (useLocalCopyValue, "Use Local Copy"),\r
+                     "Enable this to specify that the PIP file should be copied to the generated project directory instead of just referred to.");\r
+\r
+        propertyGroup.setProperties (builder);\r
+    }\r
+\r
+    //==============================================================================\r
+    void valueTreePropertyChanged (ValueTree&, const Identifier& id) override\r
+    {\r
+        if (id == Ids::type)\r
+        {\r
+            auto type = typeValue.get().toString();\r
+\r
+            if (type == "Component")\r
+            {\r
+                nameValue.setDefault ("MyComponentPIP");\r
+                dependenciesValue.setDefault (getModulesRequiredForComponent());\r
+                mainClassValue.setDefault ("MyComponent");\r
+            }\r
+            else if (type == "AudioProcessor")\r
+            {\r
+                nameValue.setDefault ("MyPluginPIP");\r
+                dependenciesValue.setDefault (getModulesRequiredForAudioProcessor());\r
+                mainClassValue.setDefault ("MyPlugin");\r
+            }\r
+            else if (type == "Console")\r
+            {\r
+                nameValue.setDefault ("MyConsolePIP");\r
+                dependenciesValue.setDefault (getModulesRequiredForConsole());\r
+                mainClassValue.setDefault ({});\r
+            }\r
+\r
+            MessageManager::callAsync ([this]\r
+            {\r
+                buildProps();\r
+                resized();\r
+            });\r
+        }\r
+    }\r
+\r
+    void valueTreeChildAdded (ValueTree&, ValueTree&) override           {}\r
+    void valueTreeChildRemoved (ValueTree&, ValueTree&, int) override    {}\r
+    void valueTreeChildOrderChanged (ValueTree&, int, int) override      {}\r
+    void valueTreeParentChanged (ValueTree&) override                    {}\r
+\r
+    //==============================================================================\r
+    String getFormattedMetadataString() const noexcept\r
+    {\r
+        StringArray metadata;\r
+\r
+        {\r
+            StringArray section;\r
+\r
+            if (nameValue.get().toString().isNotEmpty())          section.add ("  name:             " + nameValue.get().toString());\r
+            if (versionValue.get().toString().isNotEmpty())       section.add ("  version:          " + versionValue.get().toString());\r
+            if (vendorValue.get().toString().isNotEmpty())        section.add ("  vendor:           " + vendorValue.get().toString());\r
+            if (websiteValue.get().toString().isNotEmpty())       section.add ("  website:          " + websiteValue.get().toString());\r
+            if (descriptionValue.get().toString().isNotEmpty())   section.add ("  description:      " + descriptionValue.get().toString());\r
+\r
+            if (! section.isEmpty())\r
+                metadata.add (section.joinIntoString (getPreferredLinefeed()));\r
+        }\r
+\r
+        {\r
+            StringArray section;\r
+\r
+            auto dependenciesString = getWidthLimitedStringFromVarArray (dependenciesValue.get());\r
+            if (dependenciesString.isNotEmpty())                  section.add ("  dependencies:     " + dependenciesString);\r
+\r
+            auto exportersString = getWidthLimitedStringFromVarArray (exportersValue.get());\r
+            if (exportersString.isNotEmpty())                     section.add ("  exporters:        " + exportersString);\r
+\r
+            if (! section.isEmpty())\r
+                metadata.add (section.joinIntoString (getPreferredLinefeed()));\r
+        }\r
+\r
+        {\r
+            StringArray section;\r
+\r
+            if (moduleFlagsValue.get().toString().isNotEmpty())   section.add ("  moduleFlags:      " + moduleFlagsValue.get().toString());\r
+            if (definesValue.get().toString().isNotEmpty())       section.add ("  defines:          " + definesValue.get().toString());\r
+\r
+            if (! section.isEmpty())\r
+                metadata.add (section.joinIntoString (getPreferredLinefeed()));\r
+        }\r
+\r
+        {\r
+            StringArray section;\r
+\r
+            if (typeValue.get().toString().isNotEmpty())          section.add ("  type:             " + typeValue.get().toString());\r
+            if (mainClassValue.get().toString().isNotEmpty())     section.add ("  mainClass:        " + mainClassValue.get().toString());\r
+\r
+            if (! section.isEmpty())\r
+                metadata.add (section.joinIntoString (getPreferredLinefeed()));\r
+        }\r
+\r
+        {\r
+            StringArray section;\r
+\r
+            if (useLocalCopyValue.get())                          section.add ("  useLocalCopy:     " + useLocalCopyValue.get().toString());\r
+\r
+            if (! section.isEmpty())\r
+                metadata.add (section.joinIntoString (getPreferredLinefeed()));\r
+        }\r
+\r
+        return metadata.joinIntoString (String (getPreferredLinefeed()) + getPreferredLinefeed());\r
+    }\r
+\r
+    void createPIPFile (File fileToSave)\r
+    {\r
+        String fileTemplate (BinaryData::jucer_PIPTemplate_h);\r
+        fileTemplate = fileTemplate.replace ("%%pip_metadata%%", getFormattedMetadataString());\r
+\r
+        auto type = typeValue.get().toString();\r
+\r
+        if (type == "Component")\r
+        {\r
+            String componentCode (BinaryData::jucer_ContentCompSimpleTemplate_h);\r
+            componentCode = componentCode.substring (componentCode.indexOf ("class %%content_component_class%%"))\r
+                                         .replace ("%%content_component_class%%", mainClassValue.get().toString());\r
+\r
+            fileTemplate = fileTemplate.replace ("%%pip_code%%", componentCode);\r
+        }\r
+        else if (type == "AudioProcessor")\r
+        {\r
+            String audioProcessorCode (BinaryData::jucer_PIPAudioProcessorTemplate_h);\r
+            audioProcessorCode = audioProcessorCode.replace ("%%class_name%%", mainClassValue.get().toString())\r
+                                                   .replace ("%%name%%", nameValue.get().toString());\r
+\r
+            fileTemplate = fileTemplate.replace ("%%pip_code%%", audioProcessorCode);\r
+        }\r
+        else if (type == "Console")\r
+        {\r
+            String consoleCode (BinaryData::jucer_MainConsoleAppTemplate_cpp);\r
+            consoleCode = consoleCode.substring (consoleCode.indexOf ("int main (int argc, char* argv[])"));\r
+\r
+            fileTemplate = fileTemplate.replace ("%%pip_code%%", consoleCode);\r
+        }\r
+\r
+        if (fileToSave.create())\r
+            fileToSave.replaceWithText (fileTemplate);\r
+    }\r
+\r
+    //==============================================================================\r
+    ScopedPointer<LookAndFeel> lf;\r
+\r
+    Viewport propertyViewport;\r
+    PropertyGroupComponent propertyGroup  { "PIP Creator", { getIcons().juceLogo, Colours::transparentBlack } };\r
+\r
+    TextButton createButton  { "Create PIP" };\r
+\r
+    ValueTree pipTree  { "PIPSettings" };\r
+    ValueWithDefault nameValue          { pipTree, Ids::name,          nullptr, "MyComponentPIP" },\r
+                     versionValue       { pipTree, Ids::version,       nullptr },\r
+                     vendorValue        { pipTree, Ids::vendor,        nullptr },\r
+                     websiteValue       { pipTree, Ids::website,       nullptr },\r
+                     descriptionValue   { pipTree, Ids::description,   nullptr },\r
+                     dependenciesValue  { pipTree, Ids::dependencies_, nullptr, getModulesRequiredForComponent(), "," },\r
+                     exportersValue     { pipTree, Ids::exporters,     nullptr,\r
+                                          StringArray (ProjectExporter::getValueTreeNameForExporter (ProjectExporter::getCurrentPlatformExporterName()).toLowerCase()), "," },\r
+                     moduleFlagsValue   { pipTree, Ids::moduleFlags,   nullptr },\r
+                     definesValue       { pipTree, Ids::defines,       nullptr },\r
+                     typeValue          { pipTree, Ids::type,          nullptr, "Component" },\r
+                     mainClassValue     { pipTree, Ids::mainClass,     nullptr, "MyComponent" },\r
+                     useLocalCopyValue  { pipTree, Ids::useLocalCopy,  nullptr, false };\r
+\r
+    //==============================================================================\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PIPCreatorWindowComponent)\r
+};\r
index 59a0e9b39ab73c0d01b22cbfd49e35d50aed8480..f9a7647e9035c1de53cb7d62ccad1fb184cb97c5 100644 (file)
@@ -380,6 +380,7 @@ void ProjucerApplication::createFileMenu (PopupMenu& menu)
 {\r
     menu.addCommandItem (commandManager, CommandIDs::newProject);\r
     menu.addCommandItem (commandManager, CommandIDs::newProjectFromClipboard);\r
+    menu.addCommandItem (commandManager, CommandIDs::newPIP);\r
     menu.addSeparator();\r
     menu.addCommandItem (commandManager, CommandIDs::open);\r
 \r
@@ -605,7 +606,7 @@ void ProjucerApplication::createExamplesPopupMenu (PopupMenu& menu) noexcept
     }\r
 }\r
 \r
-Array<File> ProjucerApplication::getSortedExampleDirectories() const noexcept\r
+Array<File> ProjucerApplication::getSortedExampleDirectories() noexcept\r
 {\r
     Array<File> exampleDirectories;\r
 \r
@@ -619,7 +620,8 @@ Array<File> ProjucerApplication::getSortedExampleDirectories() const noexcept
     {\r
         auto exampleDirectory = iter.getFile();\r
 \r
-        if (exampleDirectory.getFileName() != "DemoRunner" && exampleDirectory.getFileName() != "Assets")\r
+        if (exampleDirectory.getNumberOfChildFiles (File::findFiles | File::ignoreHiddenFiles) > 0\r
+            && exampleDirectory.getFileName() != "DemoRunner" && exampleDirectory.getFileName() != "Assets")\r
             exampleDirectories.add (exampleDirectory);\r
     }\r
 \r
@@ -661,6 +663,16 @@ bool ProjucerApplication::findWindowAndOpenPIP (const File& pip)
     return false;\r
 }\r
 \r
+File ProjucerApplication::getJUCEExamplesDirectoryPathFromGlobal() noexcept\r
+{\r
+    auto globalPath = getAppSettings().getStoredPath (Ids::jucePath).toString();\r
+\r
+    if (globalPath.isNotEmpty())\r
+        return File (globalPath).getChildFile ("examples");\r
+\r
+    return {};\r
+}\r
+\r
 void ProjucerApplication::findAndLaunchExample (int selectedIndex)\r
 {\r
     File example;\r
@@ -688,7 +700,7 @@ void ProjucerApplication::findAndLaunchExample (int selectedIndex)
     Analytics::getInstance()->logEvent ("Example Opened", data, ProjucerAnalyticsEvent::exampleEvent);\r
 }\r
 \r
-File ProjucerApplication::findDemoRunnerExecutable() const noexcept\r
+File ProjucerApplication::findDemoRunnerExecutable() noexcept\r
 {\r
     auto buildsPath = getJUCEExamplesDirectoryPathFromGlobal().getChildFile ("DemoRunner").getChildFile ("Builds");\r
 \r
@@ -732,19 +744,25 @@ File ProjucerApplication::findDemoRunnerExecutable() const noexcept
     extension = {};\r
    #endif\r
 \r
-    auto precompiledFile = getJUCEExamplesDirectoryPathFromGlobal().getChildFile ("DemoRunner" + extension);\r
+    auto juceDir = getAppSettings().getStoredPath (Ids::jucePath).toString();\r
+\r
+    if (juceDir.isNotEmpty())\r
+    {\r
+        auto precompiledFile = File (juceDir).getChildFile ("DemoRunner" + extension);\r
+\r
+       #if JUCE_MAC\r
+        if (precompiledFile.exists())\r
+       #else\r
+        if (precompiledFile.existsAsFile())\r
+       #endif\r
+            return precompiledFile;\r
+    }\r
 \r
-   #if JUCE_MAC\r
-    if (precompiledFile.exists())\r
-   #else\r
-    if (precompiledFile.existsAsFile())\r
-   #endif\r
-        return precompiledFile;\r
 \r
     return {};\r
 }\r
 \r
-File ProjucerApplication::findDemoRunnerProject() const noexcept\r
+File ProjucerApplication::findDemoRunnerProject() noexcept\r
 {\r
     auto buildsPath = getJUCEExamplesDirectoryPathFromGlobal().getChildFile ("DemoRunner").getChildFile ("Builds");\r
 \r
@@ -756,7 +774,7 @@ File ProjucerApplication::findDemoRunnerProject() const noexcept
 \r
     if (file.exists())\r
         return file;\r
-   #elif JUCE_WINDOW\r
+   #elif JUCE_WINDOWS\r
     auto file = buildsPath.getChildFile ("VisualStudio2017").getChildFile ("DemoRunner.sln");\r
 \r
     if (file.existsAsFile())\r
@@ -885,6 +903,7 @@ void ProjucerApplication::getAllCommands (Array <CommandID>& commands)
 \r
     const CommandID ids[] = { CommandIDs::newProject,\r
                               CommandIDs::newProjectFromClipboard,\r
+                              CommandIDs::newPIP,\r
                               CommandIDs::open,\r
                               CommandIDs::launchDemoRunner,\r
                               CommandIDs::closeAllWindows,\r
@@ -919,6 +938,11 @@ void ProjucerApplication::getCommandInfo (CommandID commandID, ApplicationComman
         result.defaultKeypresses.add (KeyPress ('n', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0));\r
         break;\r
 \r
+    case CommandIDs::newPIP:\r
+        result.setInfo ("New PIP...", "Opens the PIP Creator utility for creating a new PIP", CommandCategories::general, 0);\r
+            result.defaultKeypresses.add (KeyPress ('p', ModifierKeys::commandModifier, 0));\r
+        break;\r
+\r
     case CommandIDs::launchDemoRunner:\r
        #if JUCE_LINUX\r
         if (makeProcess.isRunning())\r
@@ -1028,6 +1052,7 @@ bool ProjucerApplication::perform (const InvocationInfo& info)
     {\r
         case CommandIDs::newProject:                createNewProject(); break;\r
         case CommandIDs::newProjectFromClipboard:   createNewProjectFromClipboard(); break;\r
+        case CommandIDs::newPIP:                    createNewPIP(); break;\r
         case CommandIDs::open:                      askUserToOpenFile(); break;\r
         case CommandIDs::launchDemoRunner:          launchDemoRunner(); break;\r
         case CommandIDs::saveAll:                   openDocumentManager.saveAll(); break;\r
@@ -1077,9 +1102,9 @@ void ProjucerApplication::createNewProjectFromClipboard()
     }\r
 }\r
 \r
-void ProjucerApplication::updateNewlyOpenedProject (Project& p)\r
+void ProjucerApplication::createNewPIP()\r
 {\r
-    LiveBuildProjectSettings::updateNewlyOpenedProject (p);\r
+    showPIPCreatorWindow();\r
 }\r
 \r
 void ProjucerApplication::askUserToOpenFile()\r
@@ -1130,8 +1155,7 @@ void ProjucerApplication::showUTF8ToolWindow()
     if (utf8Window != nullptr)\r
         utf8Window->toFront (true);\r
     else\r
-        new FloatingToolWindow ("UTF-8 String Literal Converter",\r
-                                "utf8WindowPos",\r
+        new FloatingToolWindow ("UTF-8 String Literal Converter", "utf8WindowPos",\r
                                 new UTF8Component(), utf8Window, true,\r
                                 500, 500, 300, 300, 1000, 1000);\r
 }\r
@@ -1141,8 +1165,7 @@ void ProjucerApplication::showSVGPathDataToolWindow()
     if (svgPathWindow != nullptr)\r
         svgPathWindow->toFront (true);\r
     else\r
-        new FloatingToolWindow ("SVG Path Converter",\r
-                                "svgPathWindowPos",\r
+        new FloatingToolWindow ("SVG Path Converter", "svgPathWindowPos",\r
                                 new SVGPathDataComponent(), svgPathWindow, true,\r
                                 500, 500, 300, 300, 1000, 1000);\r
 }\r
@@ -1162,9 +1185,8 @@ void ProjucerApplication::showApplicationUsageDataAgreementPopup()
     if (applicationUsageDataWindow != nullptr)\r
         applicationUsageDataWindow->toFront (true);\r
     else\r
-        new FloatingToolWindow ("Application Usage Analytics",\r
-                                {}, new ApplicationUsageDataWindowComponent (isPaidOrGPL()),\r
-                                applicationUsageDataWindow, false,\r
+        new FloatingToolWindow ("Application Usage Analytics", {},\r
+                                new ApplicationUsageDataWindowComponent (isPaidOrGPL()), applicationUsageDataWindow, false,\r
                                 400, 300, 400, 300, 400, 300);\r
 }\r
 \r
@@ -1179,8 +1201,7 @@ void ProjucerApplication::showPathsWindow (bool highlightJUCEPath)
     if (pathsWindow != nullptr)\r
         pathsWindow->toFront (true);\r
     else\r
-        new FloatingToolWindow ("Global Paths",\r
-                                "pathsWindowPos",\r
+        new FloatingToolWindow ("Global Paths", "pathsWindowPos",\r
                                 new GlobalPathsWindowComponent(), pathsWindow, false,\r
                                 600, 650, 600, 650, 600, 650);\r
 \r
@@ -1194,14 +1215,19 @@ void ProjucerApplication::showEditorColourSchemeWindow()
     if (editorColourSchemeWindow != nullptr)\r
         editorColourSchemeWindow->toFront (true);\r
     else\r
-    {\r
-        new FloatingToolWindow ("Editor Colour Scheme",\r
-                                "editorColourSchemeWindowPos",\r
-                                new EditorColourSchemeWindowComponent(),\r
-                                editorColourSchemeWindow,\r
-                                false,\r
+        new FloatingToolWindow ("Editor Colour Scheme", "editorColourSchemeWindowPos",\r
+                                new EditorColourSchemeWindowComponent(), editorColourSchemeWindow, false,\r
                                 500, 500, 500, 500, 500, 500);\r
-    }\r
+}\r
+\r
+void ProjucerApplication::showPIPCreatorWindow()\r
+{\r
+    if (pipCreatorWindow != nullptr)\r
+        pipCreatorWindow->toFront (true);\r
+    else\r
+        new FloatingToolWindow ("PIP Creator", "pipCreatorWindowPos",\r
+                                new PIPCreatorWindowComponent(), pipCreatorWindow, false,\r
+                                600, 750, 600, 750, 600, 750);\r
 }\r
 \r
 void ProjucerApplication::launchForumBrowser()\r
@@ -1214,7 +1240,7 @@ void ProjucerApplication::launchForumBrowser()
 \r
 void ProjucerApplication::launchModulesBrowser()\r
 {\r
-    URL modulesLink ("https://juce.com/doc/modules");\r
+    URL modulesLink ("https://docs.juce.com/master/modules.html");\r
 \r
     if (modulesLink.isWellFormed())\r
         modulesLink.launchInDefaultBrowser();\r
@@ -1222,7 +1248,7 @@ void ProjucerApplication::launchModulesBrowser()
 \r
 void ProjucerApplication::launchClassesBrowser()\r
 {\r
-    URL classesLink ("https://juce.com/doc/classes");\r
+    URL classesLink ("https://docs.juce.com/master/classes.html");\r
 \r
     if (classesLink.isWellFormed())\r
         classesLink.launchInDefaultBrowser();\r
@@ -1230,7 +1256,7 @@ void ProjucerApplication::launchClassesBrowser()
 \r
 void ProjucerApplication::launchTutorialsBrowser()\r
 {\r
-    URL tutorialsLink ("https://juce.com/tutorials");\r
+    URL tutorialsLink ("https://juce.com/learn/tutorials");\r
 \r
     if (tutorialsLink.isWellFormed())\r
         tutorialsLink.launchInDefaultBrowser();\r
@@ -1408,6 +1434,7 @@ void ProjucerApplication::setColourScheme (int index, bool saveSetting)
     if (applicationUsageDataWindow != nullptr)  applicationUsageDataWindow->sendLookAndFeelChange();\r
     if (pathsWindow != nullptr)                 pathsWindow->sendLookAndFeelChange();\r
     if (editorColourSchemeWindow != nullptr)    editorColourSchemeWindow->sendLookAndFeelChange();\r
+    if (pipCreatorWindow != nullptr)            pipCreatorWindow->sendLookAndFeelChange();\r
 \r
     auto* mcm = ModalComponentManager::getInstance();\r
     for (auto i = 0; i < mcm->getNumModalComponents(); ++i)\r
index a9ec37b80821fa3128b9a23499c0b8c2d0695703..97b1871c4afd3542493947a18738c95957a73eb1 100644 (file)
 #include "../CodeEditor/jucer_SourceCodeEditor.h"\r
 #include "../Utility/UI/jucer_ProjucerLookAndFeel.h"\r
 #include "../Licenses/jucer_LicenseController.h"\r
-#include "jucer_ProjucerAnalytics.h"\r
+\r
+#if JUCE_MODULE_AVAILABLE_juce_analytics\r
+ #include "jucer_ProjucerAnalytics.h"\r
+#endif\r
 \r
 struct ChildProcessCache;\r
 \r
@@ -90,7 +93,7 @@ public:
     //==============================================================================\r
     void createNewProject();\r
     void createNewProjectFromClipboard();\r
-    void updateNewlyOpenedProject (Project&);\r
+    void createNewPIP();\r
     void askUserToOpenFile();\r
     bool openFile (const File&);\r
     bool closeAllDocuments (bool askUserToSave);\r
@@ -111,6 +114,8 @@ public:
     void showPathsWindow (bool highlightJUCEPath = false);\r
     void showEditorColourSchemeWindow();\r
 \r
+    void showPIPCreatorWindow();\r
+\r
     void launchForumBrowser();\r
     void launchModulesBrowser();\r
     void launchClassesBrowser();\r
@@ -147,7 +152,7 @@ public:
     ScopedPointer<ApplicationCommandManager> commandManager;\r
 \r
     ScopedPointer<Component> utf8Window, svgPathWindow, aboutWindow, applicationUsageDataWindow,\r
-                             pathsWindow, editorColourSchemeWindow;\r
+                             pathsWindow, editorColourSchemeWindow, pipCreatorWindow;\r
 \r
     ScopedPointer<FileLogger> logger;\r
 \r
@@ -174,14 +179,15 @@ private:
     void deleteTemporaryFiles() const noexcept;\r
 \r
     void createExamplesPopupMenu (PopupMenu&) noexcept;\r
-    Array<File> getSortedExampleDirectories() const noexcept;\r
+    Array<File> getSortedExampleDirectories() noexcept;\r
     Array<File> getSortedExampleFilesInDirectory (const File&) const noexcept;\r
 \r
     bool findWindowAndOpenPIP (const File&);\r
 \r
+    File getJUCEExamplesDirectoryPathFromGlobal() noexcept;\r
     void findAndLaunchExample (int);\r
-    File findDemoRunnerExecutable() const noexcept;\r
-    File findDemoRunnerProject() const noexcept;\r
+    File findDemoRunnerExecutable() noexcept;\r
+    File findDemoRunnerProject() noexcept;\r
     void launchDemoRunner();\r
 \r
     int numExamples = 0;\r
index 711e5c34f7e186b97c2a0ab482c79ce50da801e4..b8cc68ed5d98bc53b3d3d70c6f9186a481512a91 100644 (file)
@@ -35,12 +35,13 @@ namespace CommandIDs
     {\r
         newProject              = 0x300000,\r
         newProjectFromClipboard = 0x300001,\r
-        open                    = 0x300002,\r
-        closeDocument           = 0x300003,\r
-        saveDocument            = 0x300004,\r
-        saveDocumentAs          = 0x300005,\r
+        newPIP                  = 0x300002,\r
+        open                    = 0x300003,\r
+        closeDocument           = 0x300004,\r
+        saveDocument            = 0x300005,\r
+        saveDocumentAs          = 0x300006,\r
 \r
-        launchDemoRunner        = 0x300006,\r
+        launchDemoRunner        = 0x300007,\r
 \r
         closeProject            = 0x300010,\r
         saveProject             = 0x300011,\r
index 08796204d027da969cdad8e0c20201d9737038f1..c6070c74398cb6c57610a333f762211aeb05c842 100644 (file)
@@ -31,6 +31,9 @@
 \r
 #include "jucer_CommandLine.h"\r
 \r
+//==============================================================================\r
+const char* preferredLinefeed = "\r\n";\r
+const char* getPreferredLinefeed()     { return preferredLinefeed; }\r
 \r
 //==============================================================================\r
 namespace\r
@@ -62,6 +65,20 @@ namespace
             throw CommandLineError ("Not enough arguments!");\r
     }\r
 \r
+    static bool findArgument (StringArray& args, const String& target)\r
+    {\r
+        for (int i = 0; i < args.size(); ++i)\r
+        {\r
+            if (args[i].trim() == target)\r
+            {\r
+                args.remove (i);\r
+                return true;\r
+            }\r
+        }\r
+\r
+        return false;\r
+    }\r
+\r
     static File getFile (const String& filename)\r
     {\r
         return File::getCurrentWorkingDirectory().getChildFile (filename.unquoted());\r
@@ -405,9 +422,9 @@ namespace
         if (options.removeTabs && ! anyTabsRemoved)\r
             return;\r
 \r
-        const String newText = joinLinesIntoSourceFile (lines);\r
+        auto newText = joinLinesIntoSourceFile (lines);\r
 \r
-        if (newText != content && newText != content + getLineEnding())\r
+        if (newText != content && newText != content + getPreferredLinefeed())\r
             replaceFile (file, newText, options.removeTabs ? "Removing tabs in: "\r
                                                            : "Cleaning file: ");\r
     }\r
@@ -471,29 +488,28 @@ namespace
         lines.addLines (content);\r
         bool hasChanged = false;\r
 \r
-        for (int i = 0; i < lines.size(); ++i)\r
+        for (auto& line : lines)\r
         {\r
-            String line = lines[i];\r
-\r
             if (line.trimStart().startsWith ("#include \""))\r
             {\r
-                const String includedFile (line.fromFirstOccurrenceOf ("\"", true, false)\r
-                                               .upToLastOccurrenceOf ("\"", true, false)\r
-                                               .trim()\r
-                                               .unquoted());\r
+                auto includedFile = line.fromFirstOccurrenceOf ("\"", true, false)\r
+                                        .upToLastOccurrenceOf ("\"", true, false)\r
+                                        .trim()\r
+                                        .unquoted();\r
 \r
-                const File target (file.getSiblingFile (includedFile));\r
+                auto target = file.getSiblingFile (includedFile);\r
 \r
                 if (! target.exists())\r
                 {\r
-                    File header = findSimilarlyNamedHeader (allFiles, target.getFileName(), file);\r
+                    auto header = findSimilarlyNamedHeader (allFiles, target.getFileName(), file);\r
 \r
                     if (header.exists())\r
                     {\r
-                        lines.set (i, line.upToFirstOccurrenceOf ("#include \"", true, false)\r
-                                        + header.getRelativePathFrom (file.getParentDirectory())\r
-                                            .replaceCharacter ('\\', '/')\r
-                                        + "\"");\r
+                        line = line.upToFirstOccurrenceOf ("#include \"", true, false)\r
+                                  + header.getRelativePathFrom (file.getParentDirectory())\r
+                                          .replaceCharacter ('\\', '/')\r
+                                  + "\"";\r
+\r
                         hasChanged = true;\r
                     }\r
                 }\r
@@ -502,9 +518,9 @@ namespace
 \r
         if (hasChanged)\r
         {\r
-            const String newText = joinLinesIntoSourceFile (lines);\r
+            auto newText = joinLinesIntoSourceFile (lines);\r
 \r
-            if (newText != content && newText != content + getLineEnding())\r
+            if (newText != content && newText != content + getPreferredLinefeed())\r
                 replaceFile (file, newText, "Fixing includes in: ");\r
         }\r
     }\r
@@ -512,9 +528,8 @@ namespace
     static void fixRelativeIncludePaths (const StringArray& args)\r
     {\r
         checkArgumentCount (args, 2);\r
-        const File target (getDirectoryCheckingForExistence (args[1]));\r
-\r
-        Array<File> files = findAllSourceFiles (target);\r
+        auto target = getDirectoryCheckingForExistence (args[1]);\r
+        auto files = findAllSourceFiles (target);\r
 \r
         for (int i = 0; i < files.size(); ++i)\r
             fixIncludes (files.getReference(i), files);\r
@@ -553,7 +568,7 @@ namespace
                 for (int i = 0; i < text.length(); ++i)\r
                     out << " << '" << String::charToString (text[i]) << "'";\r
 \r
-                out << ";" << newLine;\r
+                out << ";" << preferredLinefeed;\r
             }\r
         };\r
 \r
@@ -577,18 +592,18 @@ namespace
 \r
         MemoryOutputStream out;\r
 \r
-        out << "String createString()" << newLine\r
-            << "{" << newLine;\r
+        out << "String createString()" << preferredLinefeed\r
+            << "{" << preferredLinefeed;\r
 \r
         for (int i = 0; i < sections.size(); ++i)\r
             sections.getReference(i).writeGenerator (out);\r
 \r
-        out << newLine\r
-            << "    String result = " << getStringConcatenationExpression (rng, 0, sections.size()) << ";" << newLine\r
-            << newLine\r
-            << "    jassert (result == " << originalText.quoted() << ");" << newLine\r
-            << "    return result;" << newLine\r
-            << "}" << newLine;\r
+        out << preferredLinefeed\r
+            << "    String result = " << getStringConcatenationExpression (rng, 0, sections.size()) << ";" << preferredLinefeed\r
+            << preferredLinefeed\r
+            << "    jassert (result == " << originalText.quoted() << ");" << preferredLinefeed\r
+            << "    return result;" << preferredLinefeed\r
+            << "}" << preferredLinefeed;\r
 \r
         std::cout << out.toString() << std::endl;\r
     }\r
@@ -646,32 +661,32 @@ namespace
 \r
         MemoryOutputStream header, cpp;\r
 \r
-        header << "// Auto-generated binary data by the Projucer" << newLine\r
-               << "// Source file: " << source.getRelativePathFrom (target.getParentDirectory()) << newLine\r
-               << newLine;\r
+        header << "// Auto-generated binary data by the Projucer" << preferredLinefeed\r
+               << "// Source file: " << source.getRelativePathFrom (target.getParentDirectory()) << preferredLinefeed\r
+               << preferredLinefeed;\r
 \r
         cpp << header.toString();\r
 \r
         if (target.hasFileExtension (headerFileExtensions))\r
         {\r
-            header << "static constexpr unsigned char " << variableName << "[] =" << newLine\r
-                   << literal.toString() << newLine\r
-                   << newLine;\r
+            header << "static constexpr unsigned char " << variableName << "[] =" << preferredLinefeed\r
+                   << literal.toString() << preferredLinefeed\r
+                   << preferredLinefeed;\r
 \r
             replaceFile (target, header.toString(), "Writing: ");\r
         }\r
         else if (target.hasFileExtension (cppFileExtensions))\r
         {\r
-            header << "extern const char*  " << variableName << ";" << newLine\r
-                   << "const unsigned int  " << variableName << "Size = " << (int) dataSize << ";" << newLine\r
-                   << newLine;\r
+            header << "extern const char*  " << variableName << ";" << preferredLinefeed\r
+                   << "const unsigned int  " << variableName << "Size = " << (int) dataSize << ";" << preferredLinefeed\r
+                   << preferredLinefeed;\r
 \r
-            cpp << CodeHelpers::createIncludeStatement (target.withFileExtension (".h").getFileName()) << newLine\r
-                << newLine\r
-                << "static constexpr unsigned char " << variableName << "_local[] =" << newLine\r
-                << literal.toString() << newLine\r
-                << newLine\r
-                << "const char* " << variableName << " = (const char*) " << variableName << "_local;" << newLine;\r
+            cpp << CodeHelpers::createIncludeStatement (target.withFileExtension (".h").getFileName()) << preferredLinefeed\r
+                << preferredLinefeed\r
+                << "static constexpr unsigned char " << variableName << "_local[] =" << preferredLinefeed\r
+                << literal.toString() << preferredLinefeed\r
+                << preferredLinefeed\r
+                << "const char* " << variableName << " = (const char*) " << variableName << "_local;" << preferredLinefeed;\r
 \r
             replaceFile (target, cpp.toString(), "Writing: ");\r
             replaceFile (target.withFileExtension (".h"), header.toString(), "Writing: ");\r
@@ -836,6 +851,8 @@ namespace
                   << std::endl\r
                   << " " << appName << " --create-project-from-pip path/to/PIP path/to/output" << std::endl\r
                   << "    Generates a JUCE project from a PIP file." << std::endl\r
+                  << std::endl\r
+                  << "Note that for any of the file-rewriting commands, add the option \"--lf\" if you want it to use LF linefeeds instead of CRLF" << std::endl\r
                   << std::endl;\r
     }\r
 }\r
@@ -847,6 +864,9 @@ int performCommandLine (const String& commandLine)
     args.addTokens (commandLine, true);\r
     args.trim();\r
 \r
+    if (findArgument (args, "--lf") || findArgument (args, "-lf"))\r
+       preferredLinefeed = "\n";\r
+\r
     String command (args[0]);\r
 \r
     try\r
index c88604bcc421dbf4912ff37719f49387fd6ff07f..85e033822135c9bc8dfaac19a4e55f878bd290e7 100644 (file)
@@ -37,6 +37,7 @@
 #include "Windows/jucer_ApplicationUsageDataWindowComponent.h"\r
 #include "Windows/jucer_EditorColourSchemeWindowComponent.h"\r
 #include "Windows/jucer_GlobalPathsWindowComponent.h"\r
+#include "Windows/jucer_PIPCreatorWindowComponent.h"\r
 #include "Windows/jucer_FloatingToolWindow.h"\r
 \r
 #include "../LiveBuildEngine/jucer_MessageIDs.h"\r
index 9ef3611d301d49c9ac7bacaf6979ae8cd2fc21ec..394d3f5cfbdc6f96a3aa02f0175d4b1ecdc15449 100644 (file)
@@ -291,7 +291,7 @@ bool MainWindow::tryToOpenPIP (const File& pipFile)
     if (! ProjucerApplication::getApp().mainWindowList.openFile (generator.getJucerFile()))\r
         return false;\r
 \r
-    openPIP (generator, pipFile.getFileName());\r
+    openPIP (generator);\r
     return true;\r
 }\r
 \r
@@ -361,7 +361,7 @@ static int findBestLineToScrollTo (StringArray lines, StringRef className)
     return 0;\r
 }\r
 \r
-void MainWindow::openPIP (PIPGenerator& generator, StringRef fileName)\r
+void MainWindow::openPIP (PIPGenerator& generator)\r
 {\r
     if (auto* window = ProjucerApplication::getApp().mainWindowList.getMainWindowForFile (generator.getJucerFile()))\r
     {\r
@@ -378,7 +378,7 @@ void MainWindow::openPIP (PIPGenerator& generator, StringRef fileName)
                 pcc->invokeDirectly (CommandIDs::buildNow, true);\r
                 pcc->invokeDirectly (CommandIDs::toggleContinuousBuild, true);\r
 \r
-                auto fileToDisplay = project->getSourceFilesFolder().getChildFile (fileName);\r
+                auto fileToDisplay = generator.getPIPFile();\r
 \r
                 if (fileToDisplay != File())\r
                 {\r
@@ -584,12 +584,12 @@ bool MainWindow::perform (const InvocationInfo& info)
     return true;\r
 }\r
 \r
-void MainWindow::valueChanged (Value& v)\r
+void MainWindow::valueChanged (Value&)\r
 {\r
-    if (v == Value())\r
-        setName ("Projucer");\r
+    if (currentProject != nullptr)\r
+        setName (currentProject->getProjectNameString() + " - Projucer");\r
     else\r
-        setName (projectNameValue.toString() + " - Projucer");\r
+        setName ("Projucer");\r
 }\r
 \r
 //==============================================================================\r
index 8675d99ee0bdb8cd0ab4ca651ad661e2708f70c7..b939acde7b86819b51609ea6858775fd7e0e03db 100644 (file)
@@ -85,7 +85,7 @@ private:
     void createProjectContentCompIfNeeded();\r
     void setTitleBarIcon();\r
 \r
-    void openPIP (PIPGenerator&, StringRef fileName);\r
+    void openPIP (PIPGenerator&);\r
 \r
     void valueChanged (Value&) override;\r
 \r
index 681a79e5ea7cfca5e352c2977f7e3a5e42ece1d2..438fcd6784903f9491158e543ae2fce26ba18262 100644 (file)
@@ -116,6 +116,14 @@ bool ProjucerAnalyticsDestination::logBatchedEvents (const Array<AnalyticsEvent>
                 break;\r
             }\r
 \r
+            case ProjucerAnalyticsEvent::startPageEvent:\r
+            {\r
+                data.set ("ec", "Start Page");\r
+                setData (event, data);\r
+\r
+                break;\r
+            }\r
+\r
             default:\r
             {\r
                 // unknown event type!\r
index 22bbdfedae30212c844415ff9829dce1b6014860..7b64f171915a9d3f4ff34e52aec677e96479931d 100644 (file)
@@ -34,7 +34,8 @@ enum ProjucerAnalyticsEvent
     appEvent,\r
     projectEvent,\r
     userEvent,\r
-    exampleEvent\r
+    exampleEvent,\r
+    startPageEvent\r
 };\r
 \r
 //==============================================================================\r
diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_PIPAudioProcessorTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_PIPAudioProcessorTemplate.h
new file mode 100644 (file)
index 0000000..32f6b8a
--- /dev/null
@@ -0,0 +1,107 @@
+class %%class_name%%  : public AudioProcessor\r
+{\r
+public:\r
+    //==============================================================================\r
+    %%class_name%%()\r
+        : AudioProcessor (BusesProperties().withInput  ("Input",  AudioChannelSet::stereo())\r
+                                           .withOutput ("Output", AudioChannelSet::stereo()))\r
+    {\r
+    }\r
+\r
+    ~%%class_name%%()\r
+    {\r
+    }\r
+\r
+    //==============================================================================\r
+    void prepareToPlay (double, int) override\r
+    {\r
+        // Use this method as the place to do any pre-playback\r
+        // initialisation that you need..\r
+    }\r
+\r
+    void releaseResources() override\r
+    {\r
+        // When playback stops, you can use this as an opportunity to free up any\r
+        // spare memory, etc.\r
+    }\r
+\r
+    void processBlock (AudioBuffer<float>& buffer, MidiBuffer&) override\r
+    {\r
+        ScopedNoDenormals noDenormals;\r
+        auto totalNumInputChannels  = getTotalNumInputChannels();\r
+        auto totalNumOutputChannels = getTotalNumOutputChannels();\r
+\r
+        // In case we have more outputs than inputs, this code clears any output\r
+        // channels that didn't contain input data, (because these aren't\r
+        // guaranteed to be empty - they may contain garbage).\r
+        // This is here to avoid people getting screaming feedback\r
+        // when they first compile a plugin, but obviously you don't need to keep\r
+        // this code if your algorithm always overwrites all the output channels.\r
+        for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)\r
+            buffer.clear (i, 0, buffer.getNumSamples());\r
+\r
+        // This is the place where you'd normally do the guts of your plugin's\r
+        // audio processing...\r
+        // Make sure to reset the state if your inner loop is processing\r
+        // the samples and the outer loop is handling the channels.\r
+        // Alternatively, you can process the samples with the channels\r
+        // interleaved by keeping the same state.\r
+        for (int channel = 0; channel < totalNumInputChannels; ++channel)\r
+        {\r
+            auto* channelData = buffer.getWritePointer (channel);\r
+\r
+            // ..do something to the data...\r
+        }\r
+    }\r
+\r
+    //==============================================================================\r
+    AudioProcessorEditor* createEditor() override          { return nullptr; }\r
+    bool hasEditor() const override                        { return false;   }\r
+\r
+    //==============================================================================\r
+    const String getName() const override                  { return "%%name%%"; }\r
+    bool acceptsMidi() const override                      { return false; }\r
+    bool producesMidi() const override                     { return false; }\r
+    double getTailLengthSeconds() const override           { return 0; }\r
+\r
+    //==============================================================================\r
+    int getNumPrograms() override                          { return 1; }\r
+    int getCurrentProgram() override                       { return 0; }\r
+    void setCurrentProgram (int) override                  {}\r
+    const String getProgramName (int) override             { return {}; }\r
+    void changeProgramName (int, const String&) override   {}\r
+\r
+    //==============================================================================\r
+    void getStateInformation (MemoryBlock& destData) override\r
+    {\r
+        // You should use this method to store your parameters in the memory block.\r
+        // You could do that either as raw data, or use the XML or ValueTree classes\r
+        // as intermediaries to make it easy to save and load complex data.\r
+    }\r
+\r
+    void setStateInformation (const void* data, int sizeInBytes) override\r
+    {\r
+        // You should use this method to restore your parameters from this memory block,\r
+        // whose contents will have been created by the getStateInformation() call.\r
+    }\r
+\r
+    //==============================================================================\r
+    bool isBusesLayoutSupported (const BusesLayout& layouts) const override\r
+    {\r
+        // This is the place where you check if the layout is supported.\r
+        // In this template code we only support mono or stereo.\r
+        if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono()\r
+            && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())\r
+            return false;\r
+\r
+        // This checks if the input layout matches the output layout\r
+        if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())\r
+            return false;\r
+\r
+        return true;\r
+    }\r
+\r
+private:\r
+    //==============================================================================\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%class_name%%)\r
+};\r
index 9a7b025a66c216beb6c3db43c29fe3de8d962543..36763f82cd9c20bf9fa421c8ffb377838241a276 100644 (file)
@@ -26,10 +26,11 @@ private:
     class MainWindow    : public DocumentWindow\r
     {\r
     public:\r
-        MainWindow (const String& name, Component* c)  : DocumentWindow (name,\r
-                                                                         Desktop::getInstance().getDefaultLookAndFeel()\r
-                                                                                               .findColour (ResizableWindow::backgroundColourId),\r
-                                                                         DocumentWindow::allButtons)\r
+        MainWindow (const String& name, Component* c, JUCEApplication& a)\r
+            : DocumentWindow (name, Desktop::getInstance().getDefaultLookAndFeel()\r
+                                                          .findColour (ResizableWindow::backgroundColourId),\r
+                              DocumentWindow::allButtons),\r
+              app (a)\r
         {\r
             setUsingNativeTitleBar (true);\r
             setContentOwned (c, true);\r
@@ -47,10 +48,13 @@ private:
 \r
         void closeButtonPressed() override\r
         {\r
-            JUCEApplication::getInstance()->systemRequestedQuit();\r
+            app.systemRequestedQuit();\r
         }\r
 \r
     private:\r
+        JUCEApplication& app;\r
+\r
+        //==============================================================================\r
         JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)\r
     };\r
     ScopedPointer<MainWindow> mainWindow;\r
diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_PIPTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_PIPTemplate.h
new file mode 100644 (file)
index 0000000..b5d9170
--- /dev/null
@@ -0,0 +1,17 @@
+/*******************************************************************************\r
+ The block below describes the properties of this PIP. A PIP is a short snippet\r
+ of code that can be read by the Projucer and used to generate a JUCE project.\r
+\r
+ BEGIN_JUCE_PIP_METADATA\r
+\r
+%%pip_metadata%%\r
+\r
+ END_JUCE_PIP_METADATA\r
+\r
+*******************************************************************************/\r
+\r
+#pragma once\r
+\r
+\r
+//==============================================================================\r
+%%pip_code%%\r
index a2087e30d407f530d2371da5c8a5d2cc115566b5..503d9d03cdccd7b84caa764787fb1fff9b418c73 100644 (file)
@@ -82,16 +82,18 @@ public:
 \r
     static Font applyNameToFont (const String& typefaceName, const Font& font)\r
     {\r
-        if (typefaceName == getDefaultFont())  return Font (font.getHeight(), font.getStyleFlags());\r
-        if (typefaceName == getDefaultSans())  return Font (Font::getDefaultSansSerifFontName(), font.getHeight(), font.getStyleFlags());\r
-        if (typefaceName == getDefaultSerif()) return Font (Font::getDefaultSerifFontName(), font.getHeight(), font.getStyleFlags());\r
-        if (typefaceName == getDefaultMono())  return Font (Font::getDefaultMonospacedFontName(), font.getHeight(), font.getStyleFlags());\r
+        auto extraKerning = font.getExtraKerningFactor();\r
+\r
+        if (typefaceName == getDefaultFont())  return Font (font.getHeight(), font.getStyleFlags()).withExtraKerningFactor (extraKerning);\r
+        if (typefaceName == getDefaultSans())  return Font (Font::getDefaultSansSerifFontName(), font.getHeight(), font.getStyleFlags()).withExtraKerningFactor (extraKerning);\r
+        if (typefaceName == getDefaultSerif()) return Font (Font::getDefaultSerifFontName(), font.getHeight(), font.getStyleFlags()).withExtraKerningFactor (extraKerning);\r
+        if (typefaceName == getDefaultMono())  return Font (Font::getDefaultMonospacedFontName(), font.getHeight(), font.getStyleFlags()).withExtraKerningFactor (extraKerning);\r
+\r
+        auto f = Font (typefaceName, font.getHeight(), font.getStyleFlags()).withExtraKerningFactor (extraKerning);\r
 \r
-        auto f = Font (typefaceName, font.getHeight(), font.getStyleFlags()).withExtraKerningFactor (font.getExtraKerningFactor());\r
         if (f.getAvailableStyles().contains (font.getTypefaceStyle()))\r
-        {\r
             f.setTypefaceStyle (font.getTypefaceStyle());\r
-        }\r
+\r
         return f;\r
     }\r
 \r
index 6c190b12f27bda90cdf3147307054fadf00e8624..5b8deb894d82657f4ee545b1e63330513229972c 100644 (file)
 #endif\r
 \r
 //==============================================================================\r
-namespace ProjectProperties\r
+static File getProjucerTempFolder() noexcept\r
 {\r
-    const Identifier liveSettingsType ("LIVE_SETTINGS");\r
    #if JUCE_MAC\r
-    const Identifier liveSettingsSubtype ("OSX");\r
-   #elif JUCE_WINDOWS\r
-    const Identifier liveSettingsSubtype ("WINDOWS");\r
-   #elif JUCE_LINUX\r
-    const Identifier liveSettingsSubtype ("LINUX");\r
+    return { "~/Library/Caches/com.juce.projucer" };\r
+   #else\r
+    return File::getSpecialLocation (File::tempDirectory).getChildFile ("com.juce.projucer");\r
    #endif\r
-\r
-    static ValueTree getLiveSettings (Project& project)\r
-    {\r
-        return project.getProjectRoot().getOrCreateChildWithName (liveSettingsType, nullptr)\r
-                                       .getOrCreateChildWithName (liveSettingsSubtype, nullptr);\r
-    }\r
-\r
-    static ValueWithDefault getLiveSetting (Project& p, const Identifier& i, var defaultValue = var())\r
-    {\r
-        auto tree = getLiveSettings (p);\r
-        return { tree, i, p.getUndoManagerFor (tree), defaultValue };\r
-    }\r
-\r
-    static ValueWithDefault  getUserHeaderPathValue (Project& p)                { return getLiveSetting    (p, Ids::headerPath); }\r
-    static ValueWithDefault  getSystemHeaderPathValue (Project& p)              { return getLiveSetting    (p, Ids::systemHeaderPath); }\r
-    static ValueWithDefault  getExtraDLLsValue (Project& p)                     { return getLiveSetting    (p, Ids::extraDLLs); }\r
-    static ValueWithDefault  getExtraCompilerFlagsValue (Project& p)            { return getLiveSetting    (p, Ids::extraCompilerFlags); }\r
-    static ValueWithDefault  getExtraPreprocessorDefsValue (Project& p)         { return getLiveSetting    (p, Ids::defines); }\r
-    static ValueWithDefault  getWindowsTargetPlatformVersionValue (Project& p)  { return getLiveSetting    (p, Ids::liveWindowsTargetPlatformVersion, "10.0.16299.0"); }\r
-\r
-    static File getProjucerTempFolder()\r
-    {\r
-       #if JUCE_MAC\r
-        return File ("~/Library/Caches/com.juce.projucer");\r
-       #else\r
-        return File::getSpecialLocation (File::tempDirectory).getChildFile ("com.juce.projucer");\r
-       #endif\r
-    }\r
-\r
-    static File getCacheLocation (Project& project)\r
-    {\r
-        auto cacheFolderName = project.getProjectFilenameRootString() + "_" + project.getProjectUIDString();\r
-\r
-       #if JUCE_DEBUG\r
-        cacheFolderName += "_debug";\r
-       #endif\r
-\r
-        return getProjucerTempFolder()\r
-                .getChildFile ("Intermediate Files")\r
-                .getChildFile (cacheFolderName);\r
-    }\r
 }\r
 \r
-//==============================================================================\r
-void LiveBuildProjectSettings::getLiveSettings (Project& project, PropertyListBuilder& props)\r
+static File getCacheLocationForProject (Project& project) noexcept\r
 {\r
-    using namespace ProjectProperties;\r
-\r
-    props.addSearchPathProperty (getUserHeaderPathValue (project), "User Header Paths", "User header search paths.");\r
-    props.addSearchPathProperty (getSystemHeaderPathValue (project), "System header paths", "System header search paths.");\r
+    auto cacheFolderName = project.getProjectFilenameRootString() + "_" + project.getProjectUIDString();\r
 \r
-    props.add (new TextPropertyComponent (getExtraPreprocessorDefsValue (project), "Preprocessor Definitions", 32768, true),\r
-               "Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace or commas "\r
-               "to separate the items - to include a space or comma in a definition, precede it with a backslash.");\r
-\r
-    props.add (new TextPropertyComponent (getExtraCompilerFlagsValue (project), "Extra Compiler Flags", 2048, true),\r
-               "Extra command-line flags to be passed to the compiler. This string can contain references to preprocessor"\r
-               " definitions in the form ${NAME_OF_DEFINITION}, which will be replaced with their values.");\r
-\r
-    props.add (new TextPropertyComponent (getExtraDLLsValue (project), "Extra Dynamic Libraries", 2048, true),\r
-               "Extra dynamic libs that the running code may require. Use new-lines or commas to separate the items.");\r
-\r
-    props.add (new TextPropertyComponent (getWindowsTargetPlatformVersionValue (project), "Windows Target Platform", 256, false),\r
-                                         "The Windows target platform to use.");\r
-}\r
-\r
-void LiveBuildProjectSettings::updateNewlyOpenedProject (Project&) { /* placeholder */ }\r
+   #if JUCE_DEBUG\r
+    cacheFolderName += "_debug";\r
+   #endif\r
 \r
-bool LiveBuildProjectSettings::isBuildDisabled (Project& p)\r
-{\r
-    const bool defaultBuildDisabled = true;\r
-    return p.getStoredProperties().getBoolValue ("buildDisabled", defaultBuildDisabled);\r
+    return getProjucerTempFolder().getChildFile ("Intermediate Files").getChildFile (cacheFolderName);\r
 }\r
 \r
-void LiveBuildProjectSettings::setBuildDisabled (Project& p, bool b)    { p.getStoredProperties().setValue ("buildDisabled", b); }\r
-bool LiveBuildProjectSettings::areWarningsDisabled (Project& p)         { return p.getStoredProperties().getBoolValue ("warningsDisabled"); }\r
-void LiveBuildProjectSettings::setWarningsDisabled (Project& p, bool b) { p.getStoredProperties().setValue ("warningsDisabled", b); }\r
-\r
 //==============================================================================\r
 class ClientIPC  : public MessageHandler,\r
                    private InterprocessConnection,\r
@@ -161,26 +93,22 @@ public:
     void launchServer()\r
     {\r
         DBG ("Client: Launching Server...");\r
-        const String pipeName ("ipc_" + String::toHexString (Random().nextInt64()));\r
 \r
-        const String command (createCommandLineForLaunchingServer (pipeName,\r
-                                                                   owner.project.getProjectUIDString(),\r
-                                                                   ProjectProperties::getCacheLocation (owner.project)));\r
+        auto pipeName = "ipc_" + String::toHexString (Random().nextInt64());\r
+        auto command = createCommandLineForLaunchingServer (pipeName, owner.project.getProjectUIDString(),\r
+                                                            getCacheLocationForProject (owner.project));\r
 \r
        #if RUN_CLANG_IN_CHILD_PROCESS\r
         if (! childProcess.start (command))\r
-        {\r
             jassertfalse;\r
-        }\r
        #else\r
         server = createClangServer (command);\r
        #endif\r
 \r
-        bool ok = connectToPipe (pipeName, 10000);\r
-        jassert (ok);\r
-\r
-        if (ok)\r
+        if (connectToPipe (pipeName, 10000))\r
             MessageTypes::sendPing (*this);\r
+        else\r
+            jassertfalse;\r
 \r
         startTimer (serverKeepAliveTimeout);\r
     }\r
@@ -317,14 +245,14 @@ public:
         build.setSystemIncludes (getSystemIncludePaths());\r
         build.setUserIncludes (getUserIncludes());\r
 \r
-        build.setGlobalDefs (getGlobalDefs (project));\r
-        build.setCompileFlags (ProjectProperties::getExtraCompilerFlagsValue (project).get().toString().trim());\r
+        build.setGlobalDefs (getGlobalDefs());\r
+        build.setCompileFlags (project.getCompileEngineSettings().getExtraCompilerFlagsString());\r
         build.setExtraDLLs (getExtraDLLs());\r
         build.setJuceModulesFolder (EnabledModuleList::findDefaultModulesFolder (project).getFullPathName());\r
 \r
         build.setUtilsCppInclude (project.getAppIncludeFile().getFullPathName());\r
 \r
-        build.setWindowsTargetPlatformVersion (ProjectProperties::getWindowsTargetPlatformVersionValue (project).get().toString());\r
+        build.setWindowsTargetPlatformVersion (project.getCompileEngineSettings().getWindowsTargetPlatformVersionString());\r
 \r
         scanForProjectFiles (project, build);\r
 \r
@@ -376,15 +304,14 @@ private:
     void valueTreeParentChanged (ValueTree&) override                            { projectStructureChanged(); }\r
     void valueTreeChildOrderChanged (ValueTree&, int, int) override              {}\r
 \r
-    static String getGlobalDefs (Project& proj)\r
+    String getGlobalDefs()\r
     {\r
         StringArray defs;\r
 \r
-        defs.add (ProjectProperties::getExtraPreprocessorDefsValue (proj).get().toString());\r
+        defs.add (project.getCompileEngineSettings().getExtraPreprocessorDefsString());\r
 \r
         {\r
-            auto projectDefines = proj.getPreprocessorDefs();\r
-            StringArray result;\r
+            auto projectDefines = project.getPreprocessorDefs();\r
 \r
             for (int i = 0; i < projectDefines.size(); ++i)\r
             {\r
@@ -398,7 +325,7 @@ private:
             }\r
         }\r
 \r
-        for (Project::ExporterIterator exporter (proj); exporter.next();)\r
+        for (Project::ExporterIterator exporter (project); exporter.next();)\r
             if (exporter->canLaunchProject())\r
                 defs.add (exporter->getExporterIdentifierMacro() + "=1");\r
 \r
@@ -422,7 +349,7 @@ private:
 \r
         if (projectItem.shouldBeCompiled())\r
         {\r
-            const File f (projectItem.getFile());\r
+            auto f = projectItem.getFile();\r
 \r
             if (f.exists())\r
                 compileUnits.add (f);\r
@@ -430,7 +357,7 @@ private:
 \r
         if (projectItem.shouldBeAddedToTargetProject() && ! projectItem.shouldBeAddedToBinaryResources())\r
         {\r
-            const File f (projectItem.getFile());\r
+            auto f = projectItem.getFile();\r
 \r
             if (f.exists())\r
                 userFiles.add (f);\r
@@ -455,11 +382,11 @@ private:
             {\r
                 if (exporter->canLaunchProject())\r
                 {\r
-                    for (const LibraryModule* m : modules)\r
+                    for (auto* m : modules)\r
                     {\r
-                        const File localModuleFolder = proj.getModules().shouldCopyModuleFilesLocally (m->moduleInfo.getID()).getValue()\r
-                                                          ? proj.getLocalModuleFolder (m->moduleInfo.getID())\r
-                                                          : m->moduleInfo.getFolder();\r
+                        auto localModuleFolder = proj.getModules().shouldCopyModuleFilesLocally (m->moduleInfo.getID()).getValue()\r
+                                                        ? proj.getLocalModuleFolder (m->moduleInfo.getID())\r
+                                                        : m->moduleInfo.getFolder();\r
 \r
 \r
                         m->findAndAddCompiledUnits (*exporter, nullptr, compileUnits,\r
@@ -477,14 +404,14 @@ private:
 \r
         for (int i = 0; ; ++i)\r
         {\r
-            const File binaryDataCpp (proj.getBinaryDataCppFile (i));\r
+            auto binaryDataCpp = proj.getBinaryDataCppFile (i);\r
             if (! binaryDataCpp.exists())\r
                 break;\r
 \r
             compileUnits.add (binaryDataCpp);\r
         }\r
 \r
-        for (int i = compileUnits.size(); --i >= 0;)\r
+        for (auto i = compileUnits.size(); --i >= 0;)\r
             if (compileUnits.getReference(i).hasFileExtension (".r"))\r
                 compileUnits.remove (i);\r
 \r
@@ -493,14 +420,14 @@ private:
 \r
     static bool doesProjectMatchSavedHeaderState (Project& project)\r
     {\r
-        ValueTree liveModules (project.getProjectRoot().getChildWithName (Ids::MODULES));\r
+        auto liveModules = project.getProjectRoot().getChildWithName (Ids::MODULES);\r
 \r
         ScopedPointer<XmlElement> xml (XmlDocument::parse (project.getFile()));\r
 \r
         if (xml == nullptr || ! xml->hasTagName (Ids::JUCERPROJECT.toString()))\r
             return false;\r
 \r
-        ValueTree diskModules (ValueTree::fromXml (*xml).getChildWithName (Ids::MODULES));\r
+        auto diskModules = ValueTree::fromXml (*xml).getChildWithName (Ids::MODULES);\r
 \r
         return liveModules.isEquivalentTo (diskModules);\r
     }\r
@@ -521,14 +448,15 @@ private:
     {\r
         StringArray paths;\r
         paths.add (project.getGeneratedCodeFolder().getFullPathName());\r
-        paths.addArray (getSearchPathsFromString (ProjectProperties::getUserHeaderPathValue (project).get().toString()));\r
+        paths.addArray (getSearchPathsFromString (project.getCompileEngineSettings().getUserHeaderPathString()));\r
+\r
         return convertSearchPathsToAbsolute (paths);\r
     }\r
 \r
     StringArray getSystemIncludePaths()\r
     {\r
         StringArray paths;\r
-        paths.addArray (getSearchPathsFromString (ProjectProperties::getSystemHeaderPathValue (project).get().toString()));\r
+        paths.addArray (getSearchPathsFromString (project.getCompileEngineSettings().getSystemHeaderPathString()));\r
 \r
         auto isVST3Host = project.getModules().isModuleEnabled ("juce_audio_processors")\r
                        && project.isConfigFlagEnabled ("JUCE_PLUGINHOST_VST3");\r
@@ -558,10 +486,10 @@ private:
 \r
     StringArray getExtraDLLs()\r
     {\r
-        StringArray dlls;\r
-        dlls.addTokens (ProjectProperties::getExtraDLLsValue (project).get().toString(), "\n\r,", StringRef());\r
+        auto dlls = StringArray::fromTokens (project.getCompileEngineSettings().getExtraDLLsString(), "\n\r,", {});\r
         dlls.trim();\r
         dlls.removeEmptyStrings();\r
+\r
         return dlls;\r
     }\r
 \r
@@ -570,14 +498,11 @@ private:
 \r
 //==============================================================================\r
 CompileEngineChildProcess::CompileEngineChildProcess (Project& p)\r
-    : project (p),\r
-      continuousRebuild (false)\r
+    : project (p)\r
 {\r
     ProjucerApplication::getApp().openDocumentManager.addListener (this);\r
-\r
     createProcess();\r
-\r
-    errorList.setWarningsEnabled (! LiveBuildProjectSettings::areWarningsDisabled (project));\r
+    errorList.setWarningsEnabled (project.getCompileEngineSettings().areWarningsEnabled());\r
 }\r
 \r
 CompileEngineChildProcess::~CompileEngineChildProcess()\r
@@ -773,7 +698,7 @@ private:
 \r
     void timerCallback() override\r
     {\r
-        if (owner.continuousRebuild)\r
+        if (owner.project.getCompileEngineSettings().isContinuousRebuildEnabled())\r
             flushEditorChanges();\r
         else\r
             stopTimer();\r
@@ -911,11 +836,6 @@ void CompileEngineChildProcess::handlePing()
 }\r
 \r
 //==============================================================================\r
-void CompileEngineChildProcess::setContinuousRebuild (bool b)\r
-{\r
-    continuousRebuild = b;\r
-}\r
-\r
 void CompileEngineChildProcess::flushEditorChanges()\r
 {\r
     for (Editor* ed : editors)\r
@@ -967,7 +887,7 @@ void CompileEngineChildProcess::handleHighlightCode (const SourceCodeRange& loca
 \r
 void CompileEngineChildProcess::cleanAllCachedFilesForProject (Project& p)\r
 {\r
-    File cacheFolder (ProjectProperties::getCacheLocation (p));\r
+    File cacheFolder (getCacheLocationForProject (p));\r
 \r
     if (cacheFolder.isDirectory())\r
         cacheFolder.deleteRecursively();\r
index 4e59717001c259b7f1646e52a63cab2c625c0830..0ca0a358976b671431aebe4b39eed76e63570f0a 100644 (file)
@@ -38,33 +38,38 @@ public:
     CompileEngineChildProcess (Project&);\r
     ~CompileEngineChildProcess();\r
 \r
+    //==============================================================================\r
     bool openedOk() const       { return process != nullptr; }\r
 \r
     void editorOpened (const File& file, CodeDocument& document);\r
     bool documentAboutToClose (OpenDocumentManager::Document*) override;\r
 \r
+    //==============================================================================\r
     void cleanAll();\r
     void openPreview (const ClassDatabase::Class&);\r
     void reinstantiatePreviews();\r
     void processActivationChanged (bool isForeground);\r
 \r
+    //==============================================================================\r
     bool canLaunchApp() const;\r
     void launchApp();\r
     bool canKillApp() const;\r
     void killApp();\r
     bool isAppRunning() const noexcept;\r
 \r
+    //==============================================================================\r
     const ClassDatabase::ClassList& getComponentList() const        { return lastComponentList; }\r
 \r
-    void setContinuousRebuild (bool continuousBuild);\r
+    //==============================================================================\r
     void flushEditorChanges();\r
-\r
     static void cleanAllCachedFilesForProject (Project&);\r
 \r
+    //==============================================================================\r
     Project& project;\r
     ActivityList activityList;\r
     ErrorList errorList;\r
 \r
+    //==============================================================================\r
     std::function<void (const String&)> crashHandler;\r
 \r
     //==============================================================================\r
@@ -93,7 +98,6 @@ private:
     class ChildProcess;\r
     ScopedPointer<ChildProcess> process, runningAppProcess;\r
     ClassDatabase::ClassList lastComponentList;\r
-    bool continuousRebuild;\r
 \r
     struct Editor;\r
     OwnedArray<Editor> editors;\r
@@ -153,16 +157,3 @@ private:
 \r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessCache)\r
 };\r
-\r
-//==============================================================================\r
-struct LiveBuildProjectSettings\r
-{\r
-    static void getLiveSettings (Project&, PropertyListBuilder&);\r
-    static void updateNewlyOpenedProject (Project& p);\r
-\r
-    static bool isBuildDisabled (Project&);\r
-    static void setBuildDisabled (Project&, bool);\r
-\r
-    static bool areWarningsDisabled (Project&);\r
-    static void setWarningsDisabled (Project&, bool);\r
-};\r
index b2e7574c88e41fbbdbf659dbb2e8293e1cce736d..b88e71ddd32c191048e1f5898f361f821af0df89 100644 (file)
@@ -144,20 +144,20 @@ private:
     }\r
 \r
    #if JUCE_MAC\r
-    static bool tryFindDLLFileInAppBundle(File &outFile)\r
+    static bool tryFindDLLFileInAppBundle (File& outFile)\r
     {\r
         File currentAppFile (File::getSpecialLocation (File::currentApplicationFile));\r
         return tryFindDLLFileInFolder (currentAppFile.getChildFile ("Contents"), outFile);\r
     }\r
    #endif\r
 \r
-    static bool tryFindDLLFileInAppFolder(File &outFile)\r
+    static bool tryFindDLLFileInAppFolder (File& outFile)\r
     {\r
         auto currentAppFile = File::getSpecialLocation (File::currentApplicationFile);\r
         return tryFindDLLFileInFolder (currentAppFile.getParentDirectory(), outFile);\r
     }\r
 \r
-    static bool tryFindDLLFileInAppConfigFolder(File &outFile)\r
+    static bool tryFindDLLFileInAppConfigFolder (File& outFile)\r
     {\r
         auto userAppDataFolder = getVersionedUserAppSupportFolder();\r
         return tryFindDLLFileInFolder (userAppDataFolder, outFile);\r
diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineSettings.h b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineSettings.h
new file mode 100644 (file)
index 0000000..1374bee
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+#pragma once\r
+\r
+\r
+//==============================================================================\r
+class CompileEngineSettings\r
+{\r
+public:\r
+    CompileEngineSettings (ValueTree& projectRoot)\r
+        : tree (projectRoot.getOrCreateChildWithName ("LIVE_SETTINGS", nullptr)\r
+                           .getOrCreateChildWithName (getLiveSettingsSubType(), nullptr)),\r
+          buildEnabledValue             (tree, Ids::buildEnabled,                 nullptr, false),\r
+          continuousRebuildEnabledValue (tree, Ids::continuousRebuildEnabled,     nullptr, false),\r
+          warningsEnabledValue          (tree, Ids::warningsEnabled,              nullptr, true),\r
+          userHeaderPathValue           (tree, Ids::headerPath,                   nullptr),\r
+          systemHeaderPathValue         (tree, Ids::systemHeaderPath,             nullptr),\r
+          extraDLLsValue                (tree, Ids::extraDLLs,                    nullptr),\r
+          extraCompilerFlagsValue       (tree, Ids::extraCompilerFlags,           nullptr),\r
+          extraPreprocessorDefsValue    (tree, Ids::defines,                      nullptr),\r
+          windowsTargetPlatformValue    (tree, Ids::windowsTargetPlatformVersion, nullptr, "10.0.16299.0")\r
+    {\r
+    }\r
+\r
+    //==============================================================================\r
+    void setBuildEnabled (bool enabled) noexcept                   { buildEnabledValue = enabled; }\r
+    void setContinuousRebuildEnabled (bool enabled) noexcept       { continuousRebuildEnabledValue = enabled; }\r
+    void setWarningsEnabled (bool enabled)                         { warningsEnabledValue = enabled; }\r
+\r
+    bool isBuildEnabled() const noexcept                           { return buildEnabledValue.get(); }\r
+    bool isContinuousRebuildEnabled() const noexcept               { return continuousRebuildEnabledValue.get(); }\r
+    bool areWarningsEnabled() const noexcept                       { return warningsEnabledValue.get(); }\r
+\r
+    String getUserHeaderPathString() const noexcept                { return userHeaderPathValue.get(); }\r
+    String getSystemHeaderPathString() const noexcept              { return systemHeaderPathValue.get(); }\r
+    String getExtraDLLsString() const noexcept                     { return extraDLLsValue.get(); }\r
+    String getExtraCompilerFlagsString() const noexcept            { return extraCompilerFlagsValue.get(); }\r
+    String getExtraPreprocessorDefsString() const noexcept         { return extraPreprocessorDefsValue.get(); }\r
+    String getWindowsTargetPlatformVersionString() const noexcept  { return windowsTargetPlatformValue.get(); }\r
+\r
+    //==============================================================================\r
+    void getLiveSettings (PropertyListBuilder& props)\r
+    {\r
+        props.addSearchPathProperty (userHeaderPathValue, "User Header Paths", "User header search paths.");\r
+        props.addSearchPathProperty (systemHeaderPathValue, "System Header Paths", "System header search paths.");\r
+\r
+        props.add (new TextPropertyComponent (extraPreprocessorDefsValue, "Preprocessor Definitions", 32768, true),\r
+                   "Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace or commas "\r
+                   "to separate the items - to include a space or comma in a definition, precede it with a backslash.");\r
+\r
+        props.add (new TextPropertyComponent (extraCompilerFlagsValue, "Extra Compiler Flags", 2048, true),\r
+                   "Extra command-line flags to be passed to the compiler. This string can contain references to preprocessor"\r
+                   " definitions in the form ${NAME_OF_DEFINITION}, which will be replaced with their values.");\r
+\r
+        props.add (new TextPropertyComponent (extraDLLsValue, "Extra Dynamic Libraries", 2048, true),\r
+                   "Extra dynamic libs that the running code may require. Use new-lines or commas to separate the items.");\r
+\r
+        props.add (new TextPropertyComponent (windowsTargetPlatformValue, "Windows Target Platform", 256, false),\r
+                   "The Windows target platform to use.");\r
+    }\r
+\r
+private:\r
+    ValueTree tree;\r
+\r
+    ValueWithDefault buildEnabledValue, continuousRebuildEnabledValue, warningsEnabledValue, userHeaderPathValue, systemHeaderPathValue,\r
+                     extraDLLsValue, extraCompilerFlagsValue, extraPreprocessorDefsValue, windowsTargetPlatformValue;\r
+\r
+    //==============================================================================\r
+    String getLiveSettingsSubType() const noexcept\r
+    {\r
+       #if JUCE_MAC\r
+        return "OSX";\r
+       #elif JUCE_WINDOWS\r
+        return "WINDOWS";\r
+       #elif JUCE_LINUX\r
+        return "LINUX";\r
+       #endif\r
+\r
+        // unknown platform?!\r
+        jassertfalse;\r
+\r
+        return {};\r
+    }\r
+\r
+    //==============================================================================\r
+};\r
index 4e8d0c54a3d51782686fb8ec5f3f48f01a260b67..c4e6064fe233ae0f3d4ad196396f98ac6610422d 100644 (file)
@@ -35,7 +35,7 @@ struct LiveBuildSettingsComponent  : public Component
         addAndMakeVisible (&group);\r
 \r
         PropertyListBuilder props;\r
-        LiveBuildProjectSettings::getLiveSettings (p, props);\r
+        p.getCompileEngineSettings().getLiveSettings (props);\r
 \r
         group.setProperties (props);\r
         group.setName ("Live Build Settings");\r
index 2f0a5d1f3395353252958c693dec81a36ddc8226..708e25a46208712992f44d03185be84a510559b3 100644 (file)
@@ -218,7 +218,7 @@ private:
 \r
             if (info.isValid())\r
             {\r
-                OwnedArray <Project::ConfigFlag> configFlags;\r
+                configFlags.clear();\r
                 LibraryModule (info).getConfigFlags (project, configFlags);\r
 \r
                 for (auto* flag : configFlags)\r
@@ -245,6 +245,7 @@ private:
         String moduleID;\r
         Value globalPathValue;\r
         Value defaultJuceModulePathValue, defaultUserModulePathValue;\r
+        OwnedArray <Project::ConfigFlag> configFlags;\r
 \r
         ReferenceCountedArray<Value::ValueSource> modulePathValueSources;\r
 \r
@@ -407,7 +408,7 @@ private:
                 for (auto missingModule : missingDependencies)\r
                 {\r
                     if (auto* info = list.getModuleWithID (missingModule))\r
-                        modules.addModule (info->moduleFolder, copyLocally, useGlobalPath);\r
+                        modules.addModule (info->moduleFolder, copyLocally, useGlobalPath, false);\r
                     else\r
                         missing.add (missingModule);\r
                 }\r
@@ -542,7 +543,8 @@ public:
         for (int i = 0; i < modules.size(); ++i)\r
             project.getModules().addModule (modules.getReference(i).moduleFolder,\r
                                             project.getModules().areMostModulesCopiedLocally(),\r
-                                            project.getModules().areMostModulesUsingGlobalPath());\r
+                                            project.getModules().areMostModulesUsingGlobalPath(),\r
+                                            true);\r
     }\r
 \r
     void addSubItems() override\r
@@ -585,7 +587,6 @@ public:
     void handlePopupMenuResult (int resultCode) override\r
     {\r
         auto& modules = project.getModules();\r
-        auto numModulesBefore = modules.getNumModules();\r
 \r
         if (resultCode == 1001)\r
         {\r
@@ -600,14 +601,6 @@ public:
             else if (resultCode < 400)\r
                 modules.addModuleInteractive (getAvailableModulesInExporterPaths() [resultCode - 300]);\r
         }\r
-\r
-        if (modules.getNumModules() == numModulesBefore + 1)\r
-        {\r
-            StringPairArray data;\r
-            data.set ("label",  modules.getModuleID (modules.getNumModules() - 1));\r
-\r
-            Analytics::getInstance()->logEvent ("Module Added", data, ProjucerAnalyticsEvent::projectEvent);\r
-        }\r
     }\r
 \r
     StringArray getAvailableModulesInGlobalJucePath()\r
@@ -625,6 +618,8 @@ public:
 \r
         for (auto p : paths)\r
         {\r
+            p = p.replace ("~", File::getSpecialLocation (File::userHomeDirectory).getFullPathName());\r
+\r
             auto f = File::createFileWithoutCheckingPath (p.trim());\r
             if (f.exists())\r
                 list.addAllModulesInFolder (f);\r
index bcf84fa1e1fe1ff2ddb3e19d39316b47bdcc97bb..19949655674e987cecf063af4a48caf60a9fc3ac 100644 (file)
@@ -263,6 +263,17 @@ public:
                 infoButtons.getLast()->setAssociatedComponent (prop);\r
                 prop->setTooltip ({}); // set the tooltip to empty so it only displays when its button is clicked\r
             }\r
+\r
+            if (auto* multiChoice = dynamic_cast<MultiChoicePropertyComponent*> (prop))\r
+            {\r
+                multiChoice->onHeightChange = [this]\r
+                {\r
+                    updateSize (getX(), getY(), getWidth());\r
+\r
+                    if (auto* parent = getParentComponent())\r
+                        parent->parentSizeChanged();\r
+                };\r
+            }\r
         }\r
     }\r
 \r
@@ -294,7 +305,8 @@ public:
 \r
             pp->setBounds (40, height, width - 50, propertyHeight);\r
 \r
-            resizePropertyComponent (pp);\r
+            if (shouldResizePropertyComponent (pp))\r
+                resizePropertyComponent (pp);\r
 \r
             height += pp->getHeight() + 10;\r
         }\r
@@ -318,21 +330,28 @@ public:
         descriptionLayout.draw (g, textArea);\r
     }\r
 \r
-    int getHeightMultiplier (PropertyComponent* pp)\r
-    {\r
-        auto availableTextWidth = ProjucerLookAndFeel::getTextWidthForPropertyComponent (pp);\r
+    OwnedArray<PropertyComponent> properties;\r
 \r
-        auto font = ProjucerLookAndFeel::getPropertyComponentFont();\r
-        auto nameWidth = font.getStringWidthFloat (pp->getName());\r
+private:\r
+    OwnedArray<InfoButton> infoButtons;\r
+    ContentViewHeader header;\r
+    AttributedString description;\r
+    TextLayout descriptionLayout;\r
+    int headerSize = 40;\r
 \r
-        return static_cast<int> (nameWidth / availableTextWidth);\r
+    //==============================================================================\r
+    bool shouldResizePropertyComponent (PropertyComponent* p)\r
+    {\r
+        if (auto* textComp = dynamic_cast<TextPropertyComponent*> (p))\r
+            return ! textComp->isTextEditorMultiLine();\r
+\r
+        return (dynamic_cast<ChoicePropertyComponent*>  (p) != nullptr\r
+             || dynamic_cast<ButtonPropertyComponent*>  (p) != nullptr\r
+             || dynamic_cast<BooleanPropertyComponent*> (p) != nullptr);\r
     }\r
 \r
     void resizePropertyComponent (PropertyComponent* pp)\r
     {\r
-        if (pp->getName() == "Dependencies")\r
-            return;\r
-\r
         for (auto i = pp->getNumChildComponents() - 1; i >= 0; --i)\r
         {\r
             auto* child = pp->getChildComponent (i);\r
@@ -342,14 +361,19 @@ public:
         }\r
     }\r
 \r
-    OwnedArray<PropertyComponent> properties;\r
+    int getHeightMultiplier (PropertyComponent* pp)\r
+    {\r
+        auto availableTextWidth = ProjucerLookAndFeel::getTextWidthForPropertyComponent (pp);\r
 \r
-private:\r
-    OwnedArray<InfoButton> infoButtons;\r
-    ContentViewHeader header;\r
-    AttributedString description;\r
-    TextLayout descriptionLayout;\r
-    int headerSize = 40;\r
+        auto font = ProjucerLookAndFeel::getPropertyComponentFont();\r
+        auto nameWidth = font.getStringWidthFloat (pp->getName());\r
+\r
+        if (availableTextWidth == 0)\r
+            return 0;\r
 \r
+        return static_cast<int> (nameWidth / availableTextWidth);\r
+    }\r
+\r
+    //==============================================================================\r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertyGroupComponent)\r
 };\r
index 1f0ce9363ea3a0e81b2ed4b64637dcedd653b828..1179e1c373c184a02b084d433c87e210317d55c3 100644 (file)
@@ -1168,7 +1168,7 @@ void ProjectContentComponent::setBuildEnabled (bool isEnabled, bool displayError
         if (! displayError)\r
             lastCrashMessage = {};\r
 \r
-        LiveBuildProjectSettings::setBuildDisabled (*project, ! isEnabled);\r
+        project->getCompileEngineSettings().setBuildEnabled (isEnabled);\r
         killChildProcess();\r
         refreshTabsIfBuildStatusChanged();\r
 \r
@@ -1208,7 +1208,7 @@ void ProjectContentComponent::handleCrash (const String& message)
 \r
 bool ProjectContentComponent::isBuildEnabled() const\r
 {\r
-    return project != nullptr && ! LiveBuildProjectSettings::isBuildDisabled (*project)\r
+    return project != nullptr && project->getCompileEngineSettings().isBuildEnabled()\r
             && CompileEngineDLL::getInstance()->isLoaded();\r
 }\r
 \r
@@ -1222,7 +1222,7 @@ void ProjectContentComponent::refreshTabsIfBuildStatusChanged()
 \r
 bool ProjectContentComponent::areWarningsEnabled() const\r
 {\r
-    return project != nullptr && ! LiveBuildProjectSettings::areWarningsDisabled (*project);\r
+    return project != nullptr && project->getCompileEngineSettings().areWarningsEnabled();\r
 }\r
 \r
 void ProjectContentComponent::updateWarningState()\r
@@ -1235,7 +1235,7 @@ void ProjectContentComponent::toggleWarnings()
 {\r
     if (project != nullptr)\r
     {\r
-        LiveBuildProjectSettings::setWarningsDisabled (*project, areWarningsEnabled());\r
+        project->getCompileEngineSettings().setWarningsEnabled (! areWarningsEnabled());\r
         updateWarningState();\r
     }\r
 }\r
@@ -1314,16 +1314,14 @@ void ProjectContentComponent::timerCallback()
 \r
 bool ProjectContentComponent::isContinuousRebuildEnabled()\r
 {\r
-    return getAppSettings().getGlobalProperties().getBoolValue ("continuousRebuild", true);\r
+    return project != nullptr && project->getCompileEngineSettings().isContinuousRebuildEnabled();\r
 }\r
 \r
 void ProjectContentComponent::setContinuousRebuildEnabled (bool b)\r
 {\r
-    if (childProcess != nullptr)\r
+    if (project != nullptr && childProcess != nullptr)\r
     {\r
-        childProcess->setContinuousRebuild (b);\r
-\r
-        getAppSettings().getGlobalProperties().setValue ("continuousRebuild", b);\r
+        project->getCompileEngineSettings().setContinuousRebuildEnabled (b);\r
         ProjucerApplication::getCommandManager().commandStatusChanged();\r
     }\r
 }\r
@@ -1331,13 +1329,8 @@ void ProjectContentComponent::setContinuousRebuildEnabled (bool b)
 ReferenceCountedObjectPtr<CompileEngineChildProcess> ProjectContentComponent::getChildProcess()\r
 {\r
     if (childProcess == nullptr && isBuildEnabled())\r
-    {\r
         childProcess = ProjucerApplication::getApp().childProcessCache->getOrCreate (*project);\r
 \r
-        if (childProcess != nullptr)\r
-            childProcess->setContinuousRebuild (isContinuousRebuildEnabled());\r
-    }\r
-\r
     return childProcess;\r
 }\r
 \r
index 830331b1fbc3e0b937deab67bea6eb4936e3c5b9..97c576e6222bb6c7d8ac1a56b178ec91ad294a83 100644 (file)
@@ -775,7 +775,7 @@ Value EnabledModuleList::shouldCopyModuleFilesLocally (const String& moduleID) c
                 .getPropertyAsValue (Ids::useLocalCopy, getUndoManager());\r
 }\r
 \r
-void EnabledModuleList::addModule (const File& moduleFolder, bool copyLocally, bool useGlobalPath)\r
+void EnabledModuleList::addModule (const File& moduleFolder, bool copyLocally, bool useGlobalPath, bool sendAnalyticsEvent)\r
 {\r
     ModuleDescription info (moduleFolder);\r
 \r
@@ -801,10 +801,13 @@ void EnabledModuleList::addModule (const File& moduleFolder, bool copyLocally, b
             for (Project::ExporterIterator exporter (project); exporter.next();)\r
                 exporter->getPathForModuleValue (moduleID) = path.toUnixStyle();\r
 \r
-            StringPairArray data;\r
-            data.set ("label", moduleID);\r
+            if (sendAnalyticsEvent)\r
+            {\r
+                StringPairArray data;\r
+                data.set ("label", moduleID);\r
 \r
-            Analytics::getInstance()->logEvent ("Module Added", data, ProjucerAnalyticsEvent::projectEvent);\r
+                Analytics::getInstance()->logEvent ("Module Added", data, ProjucerAnalyticsEvent::projectEvent);\r
+            }\r
         }\r
     }\r
 }\r
@@ -961,20 +964,20 @@ void EnabledModuleList::addModuleInteractive (const String& moduleID)
     list.scanGlobalJuceModulePath();\r
     if (auto* info = list.getModuleWithID (moduleID))\r
     {\r
-        addModule (info->moduleFolder, areMostModulesCopiedLocally(), areMostModulesUsingGlobalPath());\r
+        addModule (info->moduleFolder, areMostModulesCopiedLocally(), areMostModulesUsingGlobalPath(), true);\r
         return;\r
     }\r
 \r
     list.scanGlobalUserModulePath();\r
     if (auto* info = list.getModuleWithID (moduleID))\r
     {\r
-        addModule (info->moduleFolder, areMostModulesCopiedLocally(), areMostModulesUsingGlobalPath());\r
+        addModule (info->moduleFolder, areMostModulesCopiedLocally(), areMostModulesUsingGlobalPath(), true);\r
         return;\r
     }\r
 \r
     list.scanProjectExporterModulePaths (project);\r
     if (auto* info = list.getModuleWithID (moduleID))\r
-        addModule (info->moduleFolder, areMostModulesCopiedLocally(), false);\r
+        addModule (info->moduleFolder, areMostModulesCopiedLocally(), false, true);\r
     else\r
         addModuleFromUserSelectedFile();\r
 }\r
@@ -997,8 +1000,9 @@ void EnabledModuleList::addModuleOfferingToCopy (const File& f, bool isFromUserS
         return;\r
     }\r
 \r
-    addModule (m.moduleFolder, areMostModulesCopiedLocally(), isFromUserSpecifiedFolder ? false\r
-                                                                                        : areMostModulesUsingGlobalPath());\r
+    addModule (m.moduleFolder, areMostModulesCopiedLocally(),\r
+               isFromUserSpecifiedFolder ? false : areMostModulesUsingGlobalPath(),\r
+               true);\r
 }\r
 \r
 bool isJUCEFolder (const File& f)\r
index 2c0bbd957b7f03a0d11815c323ab6bcd7659e1f4..54d80d2d542ff0734629750f828bf83834c60984 100644 (file)
@@ -155,7 +155,7 @@ public:
     ModuleDescription getModuleInfo (const String& moduleID);\r
     File getModuleFolder (const String& moduleID);\r
 \r
-    void addModule (const File& moduleManifestFile, bool copyLocally, bool useGlobalPath);\r
+    void addModule (const File& moduleManifestFile, bool copyLocally, bool useGlobalPath, bool sendAnalyticsEvent);\r
     void addModuleInteractive (const String& moduleID);\r
     void addModuleFromUserSelectedFile();\r
     void addModuleOfferingToCopy (const File&, bool isFromUserSpecifiedFolder);\r
index ef50af9250b92c31a1b461163eee034132e5db7e..62906c718d2370f66db0b8a39c8b9256b8afa8f5 100644 (file)
@@ -82,10 +82,21 @@ const char* Project::projectFileExtension = ".jucer";
 //==============================================================================\r
 void Project::setTitle (const String& newTitle)\r
 {\r
-    projectRoot.setProperty (Ids::name, newTitle, getUndoManager());\r
-    getMainGroup().getNameValue() = newTitle;\r
+    projectNameValue = newTitle;\r
 \r
+    updateTitle();\r
+}\r
+\r
+void Project::updateTitle()\r
+{\r
+    auto projectName = getProjectNameString();\r
+\r
+    getMainGroup().getNameValue() = projectName;\r
+\r
+    pluginNameValue.setDefault (projectName);\r
+    pluginDescriptionValue.setDefault (projectName);\r
     bundleIdentifierValue.setDefault (getDefaultBundleIdentifierString());\r
+    pluginAUExportPrefixValue.setDefault (CodeHelpers::makeValidIdentifier (projectName, false, true, false) + "AU");\r
     pluginAAXIdentifierValue.setDefault (getDefaultAAXIdentifierString());\r
 }\r
 \r
@@ -203,46 +214,37 @@ void Project::initialiseProjectValues()
     preprocessorDefsValue.referTo              (projectRoot, Ids::defines,    getUndoManager());\r
     userNotesValue.referTo                     (projectRoot, Ids::userNotes,  getUndoManager());\r
 \r
-    maxBinaryFileSizeValue.referTo             (projectRoot, Ids::maxBinaryFileSize,        getUndoManager(), 10240 * 1024);\r
-    includeBinaryDataInAppConfigValue.referTo  (projectRoot, Ids::includeBinaryInAppConfig, getUndoManager(), true);\r
-    binaryDataNamespaceValue.referTo           (projectRoot, Ids::binaryDataNamespace,      getUndoManager(), "BinaryData");\r
+    maxBinaryFileSizeValue.referTo             (projectRoot, Ids::maxBinaryFileSize,         getUndoManager(), 10240 * 1024);\r
+\r
+    // this is here for backwards compatibility with old projects using the incorrect id\r
+    if (projectRoot.hasProperty ("includeBinaryInAppConfig"))\r
+         includeBinaryDataInJuceHeaderValue.referTo (projectRoot, "includeBinaryInAppConfig", getUndoManager(), true);\r
+    else\r
+        includeBinaryDataInJuceHeaderValue.referTo (projectRoot, Ids::includeBinaryInJuceHeader, getUndoManager(), true);\r
+\r
+    binaryDataNamespaceValue.referTo           (projectRoot, Ids::binaryDataNamespace,       getUndoManager(), "BinaryData");\r
 }\r
 \r
 void Project::initialiseAudioPluginValues()\r
 {\r
-    buildVSTValue.referTo                    (projectRoot, Ids::buildVST,        getUndoManager(), true);\r
-    buildVST3Value.referTo                   (projectRoot, Ids::buildVST3,       getUndoManager(), false);\r
-    buildAUValue.referTo                     (projectRoot, Ids::buildAU,         getUndoManager(), true);\r
-    buildAUv3Value.referTo                   (projectRoot, Ids::buildAUv3,       getUndoManager(), false);\r
-    buildRTASValue.referTo                   (projectRoot, Ids::buildRTAS,       getUndoManager(), false);\r
-    buildAAXValue.referTo                    (projectRoot, Ids::buildAAX,        getUndoManager(), false);\r
-    buildStandaloneValue.referTo             (projectRoot, Ids::buildStandalone, getUndoManager(), false);\r
-    enableIAAValue.referTo                   (projectRoot, Ids::enableIAA,       getUndoManager(), false);\r
-\r
-    pluginNameValue.referTo                  (projectRoot, Ids::pluginName,             getUndoManager(), getProjectNameString());\r
-    pluginDescriptionValue.referTo           (projectRoot, Ids::pluginDesc,             getUndoManager(), getProjectNameString());\r
-    pluginManufacturerValue.referTo          (projectRoot, Ids::pluginManufacturer,     getUndoManager(), "yourcompany");\r
-    pluginManufacturerCodeValue.referTo      (projectRoot, Ids::pluginManufacturerCode, getUndoManager(), "Manu");\r
-    pluginCodeValue.referTo                  (projectRoot, Ids::pluginCode,             getUndoManager(), makeValid4CC (getProjectUIDString() + getProjectUIDString()));\r
-    pluginChannelConfigsValue.referTo        (projectRoot, Ids::pluginChannelConfigs,   getUndoManager());\r
-\r
-    pluginIsSynthValue.referTo               (projectRoot, Ids::pluginIsSynth,            getUndoManager(), false);\r
-    pluginWantsMidiInputValue.referTo        (projectRoot, Ids::pluginWantsMidiIn,        getUndoManager(), false);\r
-    pluginProducesMidiOutValue.referTo       (projectRoot, Ids::pluginProducesMidiOut,    getUndoManager(), false);\r
-    pluginIsMidiEffectPluginValue.referTo    (projectRoot, Ids::pluginIsMidiEffectPlugin, getUndoManager(), false);\r
-    pluginEditorNeedsKeyFocusValue.referTo   (projectRoot, Ids::pluginEditorRequiresKeys, getUndoManager(), false);\r
-\r
-    pluginVSTCategoryValue.referTo           (projectRoot, Ids::pluginVSTCategory,          getUndoManager());\r
+    pluginFormatsValue.referTo               (projectRoot, Ids::pluginFormats,              getUndoManager(), Array<var> (Ids::buildVST.toString(), Ids::buildAU.toString()), ",");\r
+    pluginCharacteristicsValue.referTo       (projectRoot, Ids::pluginCharacteristicsValue, getUndoManager(), Array<var> (), ",");\r
+\r
+    pluginNameValue.referTo                  (projectRoot, Ids::pluginName,                 getUndoManager(), getProjectNameString());\r
+    pluginDescriptionValue.referTo           (projectRoot, Ids::pluginDesc,                 getUndoManager(), getProjectNameString());\r
+    pluginManufacturerValue.referTo          (projectRoot, Ids::pluginManufacturer,         getUndoManager(), "yourcompany");\r
+    pluginManufacturerCodeValue.referTo      (projectRoot, Ids::pluginManufacturerCode,     getUndoManager(), "Manu");\r
+    pluginCodeValue.referTo                  (projectRoot, Ids::pluginCode,                 getUndoManager(), makeValid4CC (getProjectUIDString() + getProjectUIDString()));\r
+    pluginChannelConfigsValue.referTo        (projectRoot, Ids::pluginChannelConfigs,       getUndoManager());\r
+    pluginAAXIdentifierValue.referTo         (projectRoot, Ids::aaxIdentifier,              getUndoManager(), getDefaultAAXIdentifierString());\r
     pluginAUExportPrefixValue.referTo        (projectRoot, Ids::pluginAUExportPrefix,       getUndoManager(),\r
                                               CodeHelpers::makeValidIdentifier (getProjectNameString(), false, true, false) + "AU");\r
-    pluginAUMainTypeValue.referTo            (projectRoot, Ids::pluginAUMainType,           getUndoManager());\r
-    pluginRTASCategoryValue.referTo          (projectRoot, Ids::pluginRTASCategory,         getUndoManager());\r
-    pluginRTASBypassDisabledValue.referTo    (projectRoot, Ids::pluginRTASDisableBypass,    getUndoManager());\r
-    pluginRTASMultiMonoDisabledValue.referTo (projectRoot, Ids::pluginRTASDisableMultiMono, getUndoManager());\r
-    pluginAAXIdentifierValue.referTo         (projectRoot, Ids::aaxIdentifier,              getUndoManager(), getDefaultAAXIdentifierString());\r
-    pluginAAXCategoryValue.referTo           (projectRoot, Ids::pluginAAXCategory,          getUndoManager(), "AAX_ePlugInCategory_Dynamics");\r
-    pluginAAXBypassDisabledValue.referTo     (projectRoot, Ids::pluginAAXDisableBypass,     getUndoManager());\r
-    pluginAAXMultiMonoDisabledValue.referTo  (projectRoot, Ids::pluginAAXDisableMultiMono,  getUndoManager());\r
+\r
+    pluginAUMainTypeValue.referTo            (projectRoot, Ids::pluginAUMainType,           getUndoManager(), getDefaultAUMainTypes(),    ",");\r
+    pluginVSTCategoryValue.referTo           (projectRoot, Ids::pluginVSTCategory,          getUndoManager(), getDefaultVSTCategories(),  ",");\r
+    pluginVST3CategoryValue.referTo          (projectRoot, Ids::pluginVST3Category,         getUndoManager(), getDefaultVST3Categories(), ",");\r
+    pluginRTASCategoryValue.referTo          (projectRoot, Ids::pluginRTASCategory,         getUndoManager(), getDefaultRTASCategories(), ",");\r
+    pluginAAXCategoryValue.referTo           (projectRoot, Ids::pluginAAXCategory,          getUndoManager(), getDefaultAAXCategories(),  ",");\r
 }\r
 \r
 void Project::updateOldStyleConfigList()\r
@@ -318,6 +320,147 @@ void Project::updateOldModulePaths()
         exporter->updateOldModulePaths();\r
 }\r
 \r
+Array<Identifier> Project::getLegacyPluginFormatIdentifiers() noexcept\r
+{\r
+    static Array<Identifier> legacyPluginFormatIdentifiers { Ids::buildVST, Ids::buildVST3, Ids::buildAU, Ids::buildAUv3,\r
+                                                             Ids::buildRTAS, Ids::buildAAX, Ids::buildStandalone, Ids::enableIAA };\r
+\r
+    return legacyPluginFormatIdentifiers;\r
+}\r
+\r
+Array<Identifier> Project::getLegacyPluginCharacteristicsIdentifiers() noexcept\r
+{\r
+    static Array<Identifier> legacyPluginCharacteristicsIdentifiers { Ids::pluginIsSynth, Ids::pluginWantsMidiIn, Ids::pluginProducesMidiOut,\r
+                                                                      Ids::pluginIsMidiEffectPlugin, Ids::pluginEditorRequiresKeys, Ids::pluginRTASDisableBypass,\r
+                                                                      Ids::pluginRTASDisableMultiMono, Ids::pluginAAXDisableBypass, Ids::pluginAAXDisableMultiMono };\r
+\r
+    return legacyPluginCharacteristicsIdentifiers;\r
+}\r
+\r
+void Project::coalescePluginFormatValues()\r
+{\r
+    Array<var> formatsToBuild;\r
+\r
+    for (auto& formatIdentifier : getLegacyPluginFormatIdentifiers())\r
+    {\r
+        if (projectRoot.getProperty (formatIdentifier, false))\r
+            formatsToBuild.add (formatIdentifier.toString());\r
+    }\r
+\r
+    if (formatsToBuild.size() > 0)\r
+    {\r
+        pluginFormatsValue = formatsToBuild;\r
+        shouldWriteLegacyPluginFormatSettings = true;\r
+    }\r
+}\r
+\r
+void Project::coalescePluginCharacteristicsValues()\r
+{\r
+    Array<var> pluginCharacteristics;\r
+\r
+    for (auto& characteristicIdentifier : getLegacyPluginCharacteristicsIdentifiers())\r
+    {\r
+        if (projectRoot.getProperty (characteristicIdentifier, false))\r
+            pluginCharacteristics.add (characteristicIdentifier.toString());\r
+    }\r
+\r
+    if (pluginCharacteristics.size() > 0)\r
+    {\r
+        pluginCharacteristicsValue = pluginCharacteristics;\r
+        shouldWriteLegacyPluginCharacteristicsSettings = true;\r
+    }\r
+}\r
+\r
+void Project::updatePluginCategories()\r
+{\r
+    {\r
+        auto aaxCategory = projectRoot.getProperty (Ids::pluginAAXCategory, {}).toString();\r
+\r
+        if (getAllAAXCategoryVars().contains (aaxCategory))\r
+            pluginAAXCategoryValue = aaxCategory;\r
+        else if (getAllAAXCategoryStrings().contains (aaxCategory))\r
+            pluginAAXCategoryValue = Array<var> (getAllAAXCategoryVars()[getAllAAXCategoryStrings().indexOf (aaxCategory)]);\r
+        else\r
+            pluginAAXCategoryValue.resetToDefault();\r
+    }\r
+\r
+    {\r
+        auto rtasCategory = projectRoot.getProperty (Ids::pluginRTASCategory, {}).toString();\r
+\r
+        if (getAllRTASCategoryVars().contains (rtasCategory))\r
+            pluginRTASCategoryValue = rtasCategory;\r
+        else if (getAllRTASCategoryStrings().contains (rtasCategory))\r
+            pluginRTASCategoryValue = Array<var> (getAllRTASCategoryVars()[getAllRTASCategoryStrings().indexOf (rtasCategory)]);\r
+        else\r
+            pluginRTASCategoryValue.resetToDefault();\r
+    }\r
+\r
+    {\r
+        auto vstCategory = projectRoot.getProperty (Ids::pluginVSTCategory, {}).toString();\r
+\r
+        if (vstCategory.isNotEmpty() && getAllVSTCategoryStrings().contains (vstCategory))\r
+            pluginVSTCategoryValue = Array<var> (vstCategory);\r
+        else\r
+            pluginVSTCategoryValue.resetToDefault();\r
+    }\r
+\r
+    {\r
+        auto auMainType = projectRoot.getProperty (Ids::pluginAUMainType, {}).toString();\r
+\r
+        if (auMainType.isNotEmpty())\r
+        {\r
+            if (getAllAUMainTypeVars().contains (auMainType))\r
+                pluginAUMainTypeValue = Array<var> (auMainType);\r
+            else if (getAllAUMainTypeVars().contains (auMainType.quoted ('\'')))\r
+                pluginAUMainTypeValue = Array<var> (auMainType.quoted ('\''));\r
+            else if (getAllAUMainTypeStrings().contains (auMainType))\r
+                pluginAUMainTypeValue = Array<var> (getAllAUMainTypeVars()[getAllAUMainTypeStrings().indexOf (auMainType)]);\r
+        }\r
+        else\r
+        {\r
+            pluginAUMainTypeValue.resetToDefault();\r
+        }\r
+    }\r
+}\r
+\r
+void Project::writeLegacyPluginFormatSettings()\r
+{\r
+    if (pluginFormatsValue.isUsingDefault())\r
+    {\r
+        for (auto& formatIdentifier : getLegacyPluginFormatIdentifiers())\r
+            projectRoot.removeProperty (formatIdentifier, nullptr);\r
+    }\r
+    else\r
+    {\r
+        auto formatVar = pluginFormatsValue.get();\r
+\r
+        if (auto* arr = formatVar.getArray())\r
+        {\r
+            for (auto& formatIdentifier : getLegacyPluginFormatIdentifiers())\r
+                projectRoot.setProperty (formatIdentifier, arr->contains (formatIdentifier.toString()), nullptr);\r
+        }\r
+    }\r
+}\r
+\r
+void Project::writeLegacyPluginCharacteristicsSettings()\r
+{\r
+    if (pluginFormatsValue.isUsingDefault())\r
+    {\r
+        for (auto& characteristicIdentifier : getLegacyPluginCharacteristicsIdentifiers())\r
+            projectRoot.removeProperty (characteristicIdentifier, nullptr);\r
+    }\r
+    else\r
+    {\r
+        auto characteristicsVar = pluginCharacteristicsValue.get();\r
+\r
+        if (auto* arr = characteristicsVar.getArray())\r
+        {\r
+            for (auto& characteristicIdentifier : getLegacyPluginCharacteristicsIdentifiers())\r
+                projectRoot.setProperty (characteristicIdentifier, arr->contains (characteristicIdentifier.toString()), nullptr);\r
+        }\r
+    }\r
+}\r
+\r
 //==============================================================================\r
 static int getVersionElement (StringRef v, int index)\r
 {\r
@@ -423,6 +566,10 @@ Result Project::loadDocument (const File& file)
     initialiseMainGroup();\r
     initialiseAudioPluginValues();\r
 \r
+    coalescePluginFormatValues();\r
+    coalescePluginCharacteristicsValues();\r
+    updatePluginCategories();\r
+\r
     parsedPreprocessorDefs = parsePreprocessorDefs (preprocessorDefsValue.get());\r
 \r
     removeDefunctExporters();\r
@@ -547,7 +694,7 @@ void Project::valueTreePropertyChanged (ValueTree& tree, const Identifier& prope
         }\r
         else if (property == Ids::name)\r
         {\r
-            setTitle (projectRoot [Ids::name]);\r
+            updateTitle();\r
         }\r
         else if (property == Ids::defines)\r
         {\r
@@ -557,6 +704,22 @@ void Project::valueTreePropertyChanged (ValueTree& tree, const Identifier& prope
         {\r
             sendProjectSettingAnalyticsEvent ("C++ Standard = " + cppStandardValue.get().toString());\r
         }\r
+        else if (property == Ids::pluginFormats)\r
+        {\r
+            if (shouldWriteLegacyPluginFormatSettings)\r
+                writeLegacyPluginFormatSettings();\r
+        }\r
+        else if (property == Ids::pluginCharacteristicsValue)\r
+        {\r
+            pluginAUMainTypeValue.setDefault   (getDefaultAUMainTypes());\r
+            pluginVSTCategoryValue.setDefault  (getDefaultVSTCategories());\r
+            pluginVST3CategoryValue.setDefault (getDefaultVST3Categories());\r
+            pluginRTASCategoryValue.setDefault (getDefaultRTASCategories());\r
+            pluginAAXCategoryValue.setDefault  (getDefaultAAXCategories());\r
+\r
+            if (shouldWriteLegacyPluginCharacteristicsSettings)\r
+                writeLegacyPluginCharacteristicsSettings();\r
+        }\r
 \r
         changed();\r
     }\r
@@ -823,8 +986,8 @@ void Project::createPropertyEditors (PropertyListBuilder& props)
                    "(Note that individual resource files which are larger than this size cannot be split across multiple cpp files).");\r
     }\r
 \r
-    props.add (new ChoicePropertyComponent (includeBinaryDataInAppConfigValue, "Include BinaryData in AppConfig"),\r
-                                             "Include BinaryData.h in the AppConfig.h file");\r
+    props.add (new ChoicePropertyComponent (includeBinaryDataInJuceHeaderValue, "Include BinaryData in JuceHeader"),\r
+                                             "Include BinaryData.h in the JuceHeader.h file");\r
 \r
     props.add (new TextPropertyComponent (binaryDataNamespaceValue, "BinaryData Namespace", 256, false),\r
                                           "The namespace containing the binary assests.");\r
@@ -846,77 +1009,64 @@ void Project::createPropertyEditors (PropertyListBuilder& props)
 \r
 void Project::createAudioPluginPropertyEditors (PropertyListBuilder& props)\r
 {\r
-    props.add (new ChoicePropertyComponent (buildVSTValue, "Build VST"),\r
-               "Whether the project should produce a VST plugin.");\r
-    props.add (new ChoicePropertyComponent (buildVST3Value, "Build VST3"),\r
-               "Whether the project should produce a VST3 plugin.");\r
-    props.add (new ChoicePropertyComponent (buildAUValue, "Build AudioUnit"),\r
-               "Whether the project should produce an AudioUnit plugin.");\r
-    props.add (new ChoicePropertyComponent (buildAUv3Value, "Build AudioUnit v3"),\r
-               "Whether the project should produce an AudioUnit version 3 plugin.");\r
-    props.add (new ChoicePropertyComponent (buildRTASValue, "Build RTAS"),\r
-               "Whether the project should produce an RTAS plugin.");\r
-    props.add (new ChoicePropertyComponent (buildAAXValue, "Build AAX"),\r
-               "Whether the project should produce an AAX plugin.");\r
-    props.add (new ChoicePropertyComponent (buildStandaloneValue, "Build Standalone Plug-In"),\r
-               "Whether the project should produce a standalone version of your plugin.");\r
-    props.add (new ChoicePropertyComponent (enableIAAValue, "Enable Inter-App Audio"),\r
-               "Whether a standalone plug-in should be an Inter-App Audio app. You should also enable the audio "\r
-               "background capability in the iOS exporter.");\r
+    props.add (new MultiChoicePropertyComponent (pluginFormatsValue, "Plugin Formats",\r
+                                                 { "VST", "VST3", "AU", "AUv3", "RTAS", "AAX", "Standalone", "Enable IAA" },\r
+                                                 { Ids::buildVST.toString(), Ids::buildVST3.toString(), Ids::buildAU.toString(), Ids::buildAUv3.toString(),\r
+                                                   Ids::buildRTAS.toString(), Ids::buildAAX.toString(), Ids::buildStandalone.toString(), Ids::enableIAA.toString() }),\r
+               "Plugin formats to build.");\r
+    props.add (new MultiChoicePropertyComponent (pluginCharacteristicsValue, "Plugin Characteristics",\r
+                                                 { "Plugin is a Synth", "Plugin MIDI Input", "Plugin MIDI Output", "MIDI Effect Plugin", "Plugin Editor Requires Keyboard Focus",\r
+                                                   "Disable RTAS Bypass", "Disable AAX Bypass", "Disable RTAS Multi-Mono", "Disable AAX Multi-Mono" },\r
+                                                 { Ids::pluginIsSynth.toString(), Ids::pluginWantsMidiIn.toString(), Ids::pluginProducesMidiOut.toString(),\r
+                                                   Ids::pluginIsMidiEffectPlugin.toString(), Ids::pluginEditorRequiresKeys.toString(), Ids::pluginRTASDisableBypass.toString(),\r
+                                                   Ids::pluginAAXDisableBypass.toString(), Ids::pluginRTASDisableMultiMono.toString(), Ids::pluginAAXDisableMultiMono.toString() }),\r
+              "Some characteristics of your plugin such as whether it is a synth, produces MIDI messages, accepts MIDI messages etc.");\r
 \r
     props.add (new TextPropertyComponent (pluginNameValue, "Plugin Name", 128, false),\r
                "The name of your plugin (keep it short!)");\r
     props.add (new TextPropertyComponent (pluginDescriptionValue, "Plugin Description", 256, false),\r
                "A short description of your plugin.");\r
-\r
     props.add (new TextPropertyComponent (pluginManufacturerValue, "Plugin Manufacturer", 256, false),\r
                "The name of your company (cannot be blank).");\r
     props.add (new TextPropertyComponent (pluginManufacturerCodeValue, "Plugin Manufacturer Code", 4, false),\r
                "A four-character unique ID for your company. Note that for AU compatibility, this must contain at least one upper-case letter!");\r
     props.add (new TextPropertyComponent (pluginCodeValue, "Plugin Code", 4, false),\r
                "A four-character unique ID for your plugin. Note that for AU compatibility, this must contain at least one upper-case letter!");\r
-\r
     props.add (new TextPropertyComponent (pluginChannelConfigsValue, "Plugin Channel Configurations", 1024, false),\r
                "This list is a comma-separated set list in the form {numIns, numOuts} and each pair indicates a valid plug-in "\r
                "configuration. For example {1, 1}, {2, 2} means that the plugin can be used either with 1 input and 1 output, "\r
                "or with 2 inputs and 2 outputs. If your plug-in requires side-chains, aux output buses etc., then you must leave "\r
                "this field empty and override the isBusesLayoutSupported callback in your AudioProcessor.");\r
-\r
-    props.add (new ChoicePropertyComponent (pluginIsSynthValue, "Plugin is a Synth"),\r
-               "Enable this if you want your plugin to be treated as a synth or generator. It doesn't make much difference to the plugin itself, but some hosts treat synths differently to other plugins.");\r
-\r
-    props.add (new ChoicePropertyComponent (pluginWantsMidiInputValue, "Plugin Midi Input"),\r
-               "Enable this if you want your plugin to accept midi messages.");\r
-\r
-    props.add (new ChoicePropertyComponent (pluginProducesMidiOutValue, "Plugin Midi Output"),\r
-               "Enable this if your plugin is going to produce midi messages.");\r
-\r
-    props.add (new ChoicePropertyComponent (pluginIsMidiEffectPluginValue, "Midi Effect Plugin"),\r
-               "Enable this if your plugin only processes midi and no audio.");\r
-\r
-    props.add (new ChoicePropertyComponent (pluginEditorNeedsKeyFocusValue, "Plugin Editor Requires Keyboard Focus"),\r
-               "Enable this if your plugin needs keyboard input - some hosts can be a bit funny about keyboard focus..");\r
-\r
+    props.add (new TextPropertyComponent (pluginAAXIdentifierValue, "Plugin AAX Identifier", 256, false),\r
+               "The value to use for the JucePlugin_AAXIdentifier setting");\r
     props.add (new TextPropertyComponent (pluginAUExportPrefixValue, "Plugin AU Export Prefix", 128, false),\r
                "A prefix for the names of exported entry-point functions that the component exposes - typically this will be a version of your plugin's name that can be used as part of a C++ token.");\r
 \r
-    props.add (new TextPropertyComponent (pluginAUMainTypeValue, "Plugin AU Main Type", 128, false),\r
-               "In an AU, this is the value that is set as JucePlugin_AUMainType. Leave it blank unless you want to use a custom value.");\r
+    props.add (new MultiChoicePropertyComponent (pluginAUMainTypeValue, "Plugin AU Main Type", getAllAUMainTypeStrings(), getAllAUMainTypeVars(), 1),\r
+               "AU main type.");\r
+\r
+    {\r
+        Array<var> vstCategoryVars;\r
+        for (auto s : getAllVSTCategoryStrings())\r
+            vstCategoryVars.add (s);\r
 \r
-    props.add (new TextPropertyComponent (pluginVSTCategoryValue, "VST Category", 128, false),\r
-               "In a VST, this is the value that is set as JucePlugin_VSTCategory. Leave it blank unless you want to use a custom value.");\r
+        props.add (new MultiChoicePropertyComponent (pluginVSTCategoryValue, "Plugin VST Category", getAllVSTCategoryStrings(), vstCategoryVars, 1),\r
+                   "VST category.");\r
+    }\r
 \r
-    props.add (new TextPropertyComponent (pluginRTASCategoryValue, "Plugin RTAS Category", 128, false),\r
-               "(Leave this blank if your plugin is a synth). This is one of the RTAS categories from FicPluginEnums.h, such as: ePlugInCategory_None, ePlugInCategory_EQ, ePlugInCategory_Dynamics, "\r
-               "ePlugInCategory_PitchShift, ePlugInCategory_Reverb, ePlugInCategory_Delay, "\r
-               "ePlugInCategory_Modulation, ePlugInCategory_Harmonic, ePlugInCategory_NoiseReduction, "\r
-               "ePlugInCategory_Dither, ePlugInCategory_SoundField");\r
+    {\r
+        Array<var> vst3CategoryVars;\r
+        for (auto s : getAllVST3CategoryStrings())\r
+            vst3CategoryVars.add (s);\r
 \r
-    props.add (new TextPropertyComponent (pluginAAXCategoryValue, "Plugin AAX Category", 128, false),\r
-               "This is one of the categories from the AAX_EPlugInCategory enum");\r
+        props.add (new MultiChoicePropertyComponent (pluginVST3CategoryValue, "Plugin VST3 Category", getAllVST3CategoryStrings(), vst3CategoryVars),\r
+                   "VST3 category.");\r
+    }\r
 \r
-    props.add (new TextPropertyComponent (pluginAAXIdentifierValue, "Plugin AAX Identifier", 256, false),\r
-               "The value to use for the JucePlugin_AAXIdentifier setting");\r
+    props.add (new MultiChoicePropertyComponent (pluginRTASCategoryValue, "Plugin RTAS Category", getAllRTASCategoryStrings(), getAllRTASCategoryVars()),\r
+               "RTAS category.");\r
+    props.add (new MultiChoicePropertyComponent (pluginAAXCategoryValue, "Plugin AAX Category", getAllAAXCategoryStrings(), getAllAAXCategoryVars()),\r
+               "AAX category.");\r
 }\r
 \r
 //==============================================================================\r
@@ -1431,48 +1581,77 @@ bool Project::isConfigFlagEnabled (const String& name, bool defaultIsEnabled) co
 }\r
 \r
 //==============================================================================\r
-String Project::getPluginRTASCategoryCode()\r
+String Project::getAUMainTypeString() const noexcept\r
 {\r
-    if (static_cast<bool> (isPluginSynth()))\r
-        return "ePlugInCategory_SWGenerators";\r
+    auto v = pluginAUMainTypeValue.get();\r
 \r
-    auto s = getPluginRTASCategoryString();\r
-    if (s.isEmpty())\r
-        s = "ePlugInCategory_None";\r
+    if (auto* arr = v.getArray())\r
+        return arr->getFirst().toString();\r
 \r
-    return s;\r
+    jassertfalse;\r
+    return {};\r
+}\r
+\r
+String Project::getVSTCategoryString() const noexcept\r
+{\r
+    auto v = pluginVSTCategoryValue.get();\r
+\r
+    if (auto* arr = v.getArray())\r
+        return arr->getFirst().toString();\r
+\r
+    jassertfalse;\r
+    return {};\r
+}\r
+\r
+static String getVST3CategoryStringFromSelection (Array<var> selected) noexcept\r
+{\r
+    StringArray categories;\r
+\r
+    for (auto& category : selected)\r
+        categories.add (category);\r
+\r
+    return categories.joinIntoString ("|");\r
+}\r
+\r
+String Project::getVST3CategoryString() const noexcept\r
+{\r
+    auto v = pluginVST3CategoryValue.get();\r
+\r
+    if (auto* arr = v.getArray())\r
+        return getVST3CategoryStringFromSelection (*arr);\r
+\r
+    jassertfalse;\r
+    return {};\r
 }\r
 \r
-String Project::getAUMainTypeString()\r
+int Project::getAAXCategory() const noexcept\r
 {\r
-    auto s = getPluginAUMainTypeString();\r
+    int res = 0;\r
+\r
+    auto v = pluginAAXCategoryValue.get();\r
 \r
-    if (s.isEmpty())\r
+    if (auto* arr = v.getArray())\r
     {\r
-        // Unfortunately, Rez uses a header where kAudioUnitType_MIDIProcessor is undefined\r
-        // Use aumi instead.\r
-        if      (isPluginMidiEffect())      s = "'aumi'";\r
-        else if (isPluginSynth())           s = "kAudioUnitType_MusicDevice";\r
-        else if (pluginWantsMidiInput())    s = "kAudioUnitType_MusicEffect";\r
-        else                                s = "kAudioUnitType_Effect";\r
+        for (auto c : *arr)\r
+            res |= static_cast<int> (c);\r
     }\r
 \r
-    return s;\r
+    return res;\r
 }\r
 \r
-String Project::getAUMainTypeCode()\r
+int Project::getRTASCategory() const noexcept\r
 {\r
-    auto s = getPluginAUMainTypeString();\r
+    int res = 0;\r
 \r
-    if (s.isEmpty())\r
+    auto v = pluginRTASCategoryValue.get();\r
+\r
+    if (auto* arr = v.getArray())\r
     {\r
-        if      (isPluginMidiEffect())      s = "aumi";\r
-        else if (isPluginSynth())           s = "aumu";\r
-        else if (pluginWantsMidiInput())    s = "aumf";\r
-        else                                s = "aufx";\r
+        for (auto c : *arr)\r
+            res |= static_cast<int> (c);\r
     }\r
 \r
-    return s;\r
+    return res;\r
 }\r
 \r
 String Project::getIAATypeCode()\r
@@ -1503,15 +1682,7 @@ String Project::getIAAPluginName()
     return s;\r
 }\r
 \r
-String Project::getPluginVSTCategoryString()\r
-{\r
-    auto s = pluginVSTCategoryValue.get().toString().trim();\r
-\r
-    if (s.isEmpty())\r
-        s = isPluginSynth() ? "kPlugCategSynth" : "kPlugCategEffect";\r
-    return s;\r
-}\r
-\r
+//==============================================================================\r
 bool Project::isAUPluginHost()\r
 {\r
     return getModules().isModuleEnabled ("juce_audio_processors") && isConfigFlagEnabled ("JUCE_PLUGINHOST_AU");\r
@@ -1527,6 +1698,123 @@ bool Project::isVST3PluginHost()
     return getModules().isModuleEnabled ("juce_audio_processors") && isConfigFlagEnabled ("JUCE_PLUGINHOST_VST3");\r
 }\r
 \r
+//==============================================================================\r
+StringArray Project::getAllAUMainTypeStrings() noexcept\r
+{\r
+    static StringArray auMainTypeStrings { "kAudioUnitType_Effect", "kAudioUnitType_FormatConverter", "kAudioUnitType_Generator", "kAudioUnitType_MIDIProcessor",\r
+                                           "kAudioUnitType_Mixer", "kAudioUnitType_MusicDevice", "kAudioUnitType_MusicEffect", "kAudioUnitType_OfflineEffect",\r
+                                           "kAudioUnitType_Output", "kAudioUnitType_Panner" };\r
+\r
+    return auMainTypeStrings;\r
+}\r
+\r
+Array<var> Project::getAllAUMainTypeVars() noexcept\r
+{\r
+    static Array<var> auMainTypeVars { "'aufx'", "'aufc'", "'augn'", "'aumi'",\r
+                                       "'aumx'", "'aumu'", "'aumf'", "'auol'",\r
+                                       "'auou'", "'aupn'" };\r
+\r
+    return auMainTypeVars;\r
+}\r
+\r
+Array<var> Project::getDefaultAUMainTypes() const noexcept\r
+{\r
+    if (isPluginMidiEffect())      return { "'aumi'" };\r
+    if (isPluginSynth())           return { "'aumu'" };\r
+    if (pluginWantsMidiInput())    return { "'aumf'" };\r
+\r
+    return { "'aufx'" };\r
+}\r
+\r
+StringArray Project::getAllVSTCategoryStrings() noexcept\r
+{\r
+    static StringArray vstCategoryStrings { "kPlugCategUnknown", "kPlugCategEffect", "kPlugCategSynth", "kPlugCategAnalysis", "kPlugCategMastering",\r
+                                            "kPlugCategSpacializer", "kPlugCategRoomFx", "kPlugSurroundFx", "kPlugCategRestoration", "kPlugCategOfflineProcess",\r
+                                            "kPlugCategShell", "kPlugCategGenerator" };\r
+    return vstCategoryStrings;\r
+}\r
+\r
+Array<var> Project::getDefaultVSTCategories() const noexcept\r
+{\r
+    if (isPluginSynth())\r
+        return  { "kPlugCategSynth" };\r
+\r
+    return { "kPlugCategEffect" };\r
+}\r
+\r
+StringArray Project::getAllVST3CategoryStrings() noexcept\r
+{\r
+    static StringArray vst3CategoryStrings { "Fx", "Instrument", "Spatial", "Analyzer", "Delay", "Distortion", "EQ", "Filter", "Generator", "Mastering",\r
+                                             "Modulation", "Pitch Shift", "Restoration", "Reverb", "Surround", "Tools", "Network", "Drum", "Sampler",\r
+                                             "Synth", "External", "OnlyRT", "OnlyOfflineProcess", "NoOfflineProcess", "Up-Downmix" };\r
+\r
+    return vst3CategoryStrings;\r
+}\r
+\r
+Array<var> Project::getDefaultVST3Categories() const noexcept\r
+{\r
+    if (isPluginSynth())\r
+        return  { "Instrument", "Synth" };\r
+\r
+    return { "Fx" };\r
+}\r
+\r
+StringArray Project::getAllAAXCategoryStrings() noexcept\r
+{\r
+    static StringArray aaxCategoryStrings { "AAX_ePlugInCategory_None", "AAX_ePlugInCategory_EQ", "AAX_ePlugInCategory_Dynamics", "AAX_ePlugInCategory_PitchShift",\r
+                                            "AAX_ePlugInCategory_Reverb", "AAX_ePlugInCategory_Delay", "AAX_ePlugInCategory_Modulation", "AAX_ePlugInCategory_Harmonic",\r
+                                            "AAX_ePlugInCategory_NoiseReduction", "AAX_ePlugInCategory_Dither", "AAX_ePlugInCategory_SoundField", "AAX_ePlugInCategory_HWGenerators",\r
+                                            "AAX_ePlugInCategory_SWGenerators", "AAX_ePlugInCategory_WrappedPlugin", "AAX_EPlugInCategory_Effect" };\r
+\r
+    return aaxCategoryStrings;\r
+}\r
+\r
+Array<var> Project::getAllAAXCategoryVars() noexcept\r
+{\r
+    static Array<var> aaxCategoryVars { 0x00000000, 0x00000001, 0x00000002, 0x00000004,\r
+                                        0x00000008, 0x00000010, 0x00000020, 0x00000040,\r
+                                        0x00000080, 0x00000100, 0x00000200, 0x00000400,\r
+                                        0x00000800, 0x00001000, 0x00002000 };\r
+\r
+    return aaxCategoryVars;\r
+}\r
+\r
+Array<var> Project::getDefaultAAXCategories() const noexcept\r
+{\r
+    if (isPluginSynth())\r
+        return getAllAAXCategoryVars()[getAllAAXCategoryStrings().indexOf ("AAX_ePlugInCategory_SWGenerators")];\r
+\r
+    return getAllAAXCategoryVars()[getAllAAXCategoryStrings().indexOf ("AAX_ePlugInCategory_None")];\r
+}\r
+\r
+StringArray Project::getAllRTASCategoryStrings() noexcept\r
+{\r
+    static StringArray rtasCategoryStrings { "ePlugInCategory_None", "ePlugInCategory_EQ", "ePlugInCategory_Dynamics", "ePlugInCategory_PitchShift",\r
+                                             "ePlugInCategory_Reverb", "ePlugInCategory_Delay", "ePlugInCategory_Modulation", "ePlugInCategory_Harmonic",\r
+                                             "ePlugInCategory_NoiseReduction", "ePlugInCategory_Dither", "ePlugInCategory_SoundField", "ePlugInCategory_HWGenerators",\r
+                                             "ePlugInCategory_SWGenerators", "ePlugInCategory_WrappedPlugin", "ePlugInCategory_Effect" };\r
+\r
+    return rtasCategoryStrings;\r
+}\r
+\r
+Array<var> Project::getAllRTASCategoryVars() noexcept\r
+{\r
+    static Array<var> rtasCategoryVars { 0x00000000, 0x00000001, 0x00000002, 0x00000004,\r
+                                         0x00000008, 0x00000010, 0x00000020, 0x00000040,\r
+                                         0x00000080, 0x00000100, 0x00000200, 0x00000400,\r
+                                         0x00000800, 0x00001000, 0x00002000 };\r
+\r
+    return rtasCategoryVars;\r
+}\r
+\r
+Array<var> Project::getDefaultRTASCategories() const noexcept\r
+{\r
+    if (isPluginSynth())\r
+        return getAllRTASCategoryVars()[getAllRTASCategoryStrings().indexOf ("ePlugInCategory_SWGenerators")];\r
+\r
+    return getAllRTASCategoryVars()[getAllRTASCategoryStrings().indexOf ("ePlugInCategory_None")];\r
+}\r
+\r
 //==============================================================================\r
 EnabledModuleList& Project::getModules()\r
 {\r
index d5086a9ce6bfc405b8abbd8516dede5ed1e7078a..be5230462e2026ab8fdfc48d8fe51222346c9fb0 100644 (file)
@@ -27,6 +27,7 @@
 #pragma once\r
 \r
 #include "jucer_ProjectType.h"\r
+#include "../LiveBuildEngine/jucer_CompileEngineSettings.h"\r
 \r
 class ProjectExporter;\r
 class LibraryModule;\r
@@ -115,7 +116,7 @@ public:
     StringPairArray getPreprocessorDefs() const          { return parsedPreprocessorDefs; }\r
 \r
     int getMaxBinaryFileSize() const                     { return maxBinaryFileSizeValue.get(); }\r
-    bool shouldIncludeBinaryInAppConfig() const          { return includeBinaryDataInAppConfigValue.get(); }\r
+    bool shouldIncludeBinaryInJuceHeader() const         { return includeBinaryDataInJuceHeaderValue.get(); }\r
     String getBinaryDataNamespaceString() const          { return binaryDataNamespaceValue.get(); }\r
 \r
     bool shouldDisplaySplashScreen() const               { return displaySplashScreenValue.get(); }\r
@@ -124,16 +125,6 @@ public:
 \r
     String getCppStandardString() const                  { return cppStandardValue.get(); }\r
 \r
-    //==============================================================================\r
-    bool shouldBuildVST() const                 { return buildVSTValue.get(); }\r
-    bool shouldBuildVST3() const                { return buildVST3Value.get(); }\r
-    bool shouldBuildAU() const                  { return buildAUValue.get(); }\r
-    bool shouldBuildAUv3() const                { return buildAUv3Value.get(); }\r
-    bool shouldBuildRTAS() const                { return buildRTASValue.get(); }\r
-    bool shouldBuildAAX() const                 { return buildAAXValue.get(); }\r
-    bool shouldBuildStandalonePlugin() const    { return buildStandaloneValue.get(); }\r
-    bool shouldEnableIAA() const                { return enableIAAValue.get(); }\r
-\r
     //==============================================================================\r
     String getPluginNameString() const                { return pluginNameValue.get(); }\r
     String getPluginDescriptionString() const         { return pluginDescriptionValue.get();}\r
@@ -141,29 +132,74 @@ public:
     String getPluginManufacturerCodeString() const    { return pluginManufacturerCodeValue.get(); }\r
     String getPluginCodeString() const                { return pluginCodeValue.get(); }\r
     String getPluginChannelConfigsString() const      { return pluginChannelConfigsValue.get(); }\r
+    String getAAXIdentifierString() const             { return pluginAAXIdentifierValue.get(); }\r
     String getPluginAUExportPrefixString() const      { return pluginAUExportPrefixValue.get(); }\r
     String getPluginAUMainTypeString() const          { return pluginAUMainTypeValue.get(); }\r
-    String getPluginRTASCategoryString() const        { return pluginRTASCategoryValue.get(); }\r
-    String getAAXIdentifierString() const             { return pluginAAXIdentifierValue.get(); }\r
-    String getPluginAAXCategoryString() const         { return pluginAAXCategoryValue.get(); }\r
-\r
-    bool isPluginSynth() const                        { return pluginIsSynthValue.get(); }\r
-    bool pluginWantsMidiInput() const                 { return pluginWantsMidiInputValue.get(); }\r
-    bool pluginProducesMidiOutput() const             { return pluginProducesMidiOutValue.get(); }\r
-    bool isPluginMidiEffect() const                   { return pluginIsMidiEffectPluginValue.get(); }\r
-    bool pluginEditorNeedsKeyFocus() const            { return pluginEditorNeedsKeyFocusValue.get(); }\r
-    bool isPluginRTASBypassDisabled() const           { return pluginRTASBypassDisabledValue.get(); }\r
-    bool isPluginRTASMultiMonoDisabled() const        { return pluginRTASMultiMonoDisabledValue.get(); }\r
-    bool isPluginAAXBypassDisabled() const            { return pluginAAXBypassDisabledValue.get(); }\r
-    bool isPluginAAXMultiMonoDisabled() const         { return pluginAAXMultiMonoDisabledValue.get(); }\r
-\r
-    String getPluginRTASCategoryCode();\r
-    String getAUMainTypeString();\r
-    String getAUMainTypeCode();\r
+\r
+    //==============================================================================\r
+    static bool checkMultiChoiceVar (const ValueWithDefault& valueToCheck, Identifier idToCheck) noexcept\r
+    {\r
+        if (! valueToCheck.get().isArray())\r
+            return false;\r
+\r
+        auto v = valueToCheck.get();\r
+\r
+        if (auto* varArray = v.getArray())\r
+            return varArray->contains (idToCheck.toString());\r
+\r
+        return false;\r
+    }\r
+\r
+    //==============================================================================\r
+    bool shouldBuildVST() const                       { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildVST); }\r
+    bool shouldBuildVST3() const                      { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildVST3); }\r
+    bool shouldBuildAU() const                        { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildAU); }\r
+    bool shouldBuildAUv3() const                      { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildAUv3); }\r
+    bool shouldBuildRTAS() const                      { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildRTAS); }\r
+    bool shouldBuildAAX() const                       { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildAAX); }\r
+    bool shouldBuildStandalonePlugin() const          { return checkMultiChoiceVar (pluginFormatsValue, Ids::buildStandalone); }\r
+    bool shouldEnableIAA() const                      { return checkMultiChoiceVar (pluginFormatsValue, Ids::enableIAA); }\r
+\r
+    //==============================================================================\r
+    bool isPluginSynth() const                        { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginIsSynth); }\r
+    bool pluginWantsMidiInput() const                 { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginWantsMidiIn); }\r
+    bool pluginProducesMidiOutput() const             { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginProducesMidiOut); }\r
+    bool isPluginMidiEffect() const                   { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginIsMidiEffectPlugin); }\r
+    bool pluginEditorNeedsKeyFocus() const            { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginEditorRequiresKeys); }\r
+    bool isPluginRTASBypassDisabled() const           { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginRTASDisableBypass); }\r
+    bool isPluginRTASMultiMonoDisabled() const        { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginRTASDisableMultiMono); }\r
+    bool isPluginAAXBypassDisabled() const            { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginAAXDisableBypass); }\r
+    bool isPluginAAXMultiMonoDisabled() const         { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginAAXDisableMultiMono); }\r
+\r
+    //==============================================================================\r
+    static StringArray getAllAUMainTypeStrings() noexcept;\r
+    static Array<var> getAllAUMainTypeVars() noexcept;\r
+    Array<var> getDefaultAUMainTypes() const noexcept;\r
+\r
+    static StringArray getAllVSTCategoryStrings() noexcept;\r
+    Array<var> getDefaultVSTCategories() const noexcept;\r
+\r
+    static StringArray getAllVST3CategoryStrings() noexcept;\r
+    Array<var> getDefaultVST3Categories() const noexcept;\r
+\r
+    static StringArray getAllAAXCategoryStrings() noexcept;\r
+    static Array<var> getAllAAXCategoryVars() noexcept;\r
+    Array<var> getDefaultAAXCategories() const noexcept;\r
+\r
+    static StringArray getAllRTASCategoryStrings() noexcept;\r
+    static Array<var> getAllRTASCategoryVars() noexcept;\r
+    Array<var> getDefaultRTASCategories() const noexcept;\r
+\r
+    String getAUMainTypeString() const noexcept;\r
+    String getVSTCategoryString() const noexcept;\r
+    String getVST3CategoryString() const noexcept;\r
+    int getAAXCategory() const noexcept;\r
+    int getRTASCategory() const noexcept;\r
+\r
     String getIAATypeCode();\r
     String getIAAPluginName();\r
-    String getPluginVSTCategoryString();\r
 \r
+    //==============================================================================\r
     bool isAUPluginHost();\r
     bool isVSTPluginHost();\r
     bool isVST3PluginHost();\r
@@ -347,19 +383,36 @@ public:
     //==============================================================================\r
     bool shouldSendGUIBuilderAnalyticsEvent() noexcept;\r
 \r
+    //==============================================================================\r
+    CompileEngineSettings& getCompileEngineSettings()    { return compileEngineSettings; }\r
+\r
 private:\r
     ValueTree projectRoot  { Ids::JUCERPROJECT };\r
 \r
     ValueWithDefault projectNameValue, projectUIDValue, projectTypeValue, versionValue, bundleIdentifierValue, companyNameValue, companyCopyrightValue,\r
                      companyWebsiteValue, companyEmailValue, displaySplashScreenValue, reportAppUsageValue, splashScreenColourValue, cppStandardValue,\r
-                     headerSearchPathsValue, preprocessorDefsValue, userNotesValue, maxBinaryFileSizeValue, includeBinaryDataInAppConfigValue, binaryDataNamespaceValue;\r
+                     headerSearchPathsValue, preprocessorDefsValue, userNotesValue, maxBinaryFileSizeValue, includeBinaryDataInJuceHeaderValue, binaryDataNamespaceValue;\r
+\r
+    ValueWithDefault pluginFormatsValue, pluginNameValue, pluginDescriptionValue, pluginManufacturerValue, pluginManufacturerCodeValue,\r
+                     pluginCodeValue, pluginChannelConfigsValue, pluginCharacteristicsValue, pluginAUExportPrefixValue, pluginAAXIdentifierValue,\r
+                     pluginAUMainTypeValue, pluginRTASCategoryValue, pluginVSTCategoryValue, pluginVST3CategoryValue, pluginAAXCategoryValue;\r
+\r
+    //==============================================================================\r
+    CompileEngineSettings compileEngineSettings  { projectRoot };\r
+\r
+    //==============================================================================\r
+    bool shouldWriteLegacyPluginFormatSettings = false;\r
+    bool shouldWriteLegacyPluginCharacteristicsSettings = false;\r
+\r
+    static Array<Identifier> getLegacyPluginFormatIdentifiers() noexcept;\r
+    static Array<Identifier> getLegacyPluginCharacteristicsIdentifiers() noexcept;\r
+\r
+    void writeLegacyPluginFormatSettings();\r
+    void writeLegacyPluginCharacteristicsSettings();\r
 \r
-    ValueWithDefault buildVSTValue, buildVST3Value, buildAUValue, buildAUv3Value, buildRTASValue, buildAAXValue, buildStandaloneValue,\r
-                     enableIAAValue, pluginNameValue, pluginDescriptionValue, pluginManufacturerValue, pluginManufacturerCodeValue,\r
-                     pluginCodeValue, pluginChannelConfigsValue, pluginIsSynthValue, pluginWantsMidiInputValue, pluginProducesMidiOutValue,\r
-                     pluginIsMidiEffectPluginValue, pluginEditorNeedsKeyFocusValue, pluginVSTCategoryValue, pluginAUExportPrefixValue,\r
-                     pluginAUMainTypeValue, pluginRTASCategoryValue, pluginRTASBypassDisabledValue, pluginRTASMultiMonoDisabledValue,\r
-                     pluginAAXIdentifierValue, pluginAAXCategoryValue, pluginAAXBypassDisabledValue, pluginAAXMultiMonoDisabledValue;\r
+    void coalescePluginFormatValues();\r
+    void coalescePluginCharacteristicsValues();\r
+    void updatePluginCategories();\r
 \r
     //==============================================================================\r
     File tempDirectory = {};\r
@@ -389,6 +442,7 @@ private:
     void createAudioPluginPropertyEditors (PropertyListBuilder& props);\r
 \r
     //==============================================================================\r
+    void updateTitle();\r
     void updateProjectSettings();\r
     ValueTree getConfigurations() const;\r
     ValueTree getConfigNode();\r
index a3575883dd93bd01cebaa837ff348521b431c47b..4fb13afe0fe4c873c1f4f7f71b6331084f75e311 100644 (file)
@@ -141,22 +141,22 @@ public:
           androidKeyStorePass                  (settings, Ids::androidKeyStorePass,                  getUndoManager(), "android"),\r
           androidKeyAlias                      (settings, Ids::androidKeyAlias,                      getUndoManager(), "androiddebugkey"),\r
           androidKeyAliasPass                  (settings, Ids::androidKeyAliasPass,                  getUndoManager(), "android"),\r
-          gradleVersion                        (settings, Ids::gradleVersion,                        getUndoManager(), "4.1"),\r
+          gradleVersion                        (settings, Ids::gradleVersion,                        getUndoManager(), "4.4"),\r
           gradleToolchain                      (settings, Ids::gradleToolchain,                      getUndoManager(), "clang"),\r
-          androidPluginVersion                 (settings, Ids::androidPluginVersion,                 getUndoManager(), "3.0.1"),\r
-          buildToolsVersion                    (settings, Ids::buildToolsVersion,                    getUndoManager(), "27.0.0"),\r
+          androidPluginVersion                 (settings, Ids::androidPluginVersion,                 getUndoManager(), "3.1.1"),\r
+          buildToolsVersion                    (settings, Ids::buildToolsVersion,                    getUndoManager(), "27.0.3"),\r
           AndroidExecutable (findAndroidExecutable())\r
     {\r
         name = getName();\r
 \r
-        targetLocationValue.setDefault (getDefaultBuildsRootFolder() + "Android");\r
+        targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderForExporter (getValueTreeTypeName()));\r
     }\r
 \r
     //==============================================================================\r
     void createToolchainExporterProperties (PropertyListBuilder& props)\r
     {\r
         props.add (new TextPropertyComponent (gradleVersion, "gradle version", 32, false),\r
-                   "The version of gradle that is used to build this app (3.3 is fine for JUCE)");\r
+                   "The version of gradle that is used to build this app (4.4 is fine for JUCE)");\r
 \r
         props.add (new TextPropertyComponent (androidPluginVersion, "android plug-in version", 32, false),\r
                    "The version of the android build plugin for gradle that is used to build this app");\r
@@ -577,8 +577,8 @@ private:
 \r
         mo << "buildscript {"                                                                              << newLine;\r
         mo << "   repositories {"                                                                          << newLine;\r
-        mo << "       jcenter()"                                                                           << newLine;\r
         mo << "       google()"                                                                            << newLine;\r
+        mo << "       jcenter()"                                                                           << newLine;\r
         mo << "   }"                                                                                       << newLine;\r
         mo << "   dependencies {"                                                                          << newLine;\r
         mo << "       classpath 'com.android.tools.build:gradle:" << androidPluginVersion.get().toString() << "'" << newLine;\r
@@ -591,6 +591,7 @@ private:
         mo << ""                                                                                       << newLine;\r
         mo << "allprojects {"                                                                          << newLine;\r
         mo << "   repositories {"                                                                      << newLine;\r
+        mo << "       google()"                                                                        << newLine;\r
         mo << "       jcenter()"                                                                       << newLine;\r
 \r
         if (androidEnableRemoteNotifications.get())\r
index 9bea8081140487b08619dc61eea4569cf2a96ef9..be3fc51f611e63dc55337c08e30b0a50ce9f1ba0 100644 (file)
@@ -74,7 +74,7 @@ public:
     {\r
         name = getName();\r
 \r
-        targetLocationValue.setDefault (getDefaultBuildsRootFolder() + "CLion");\r
+        targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderForExporter (getValueTreeTypeName()));\r
     }\r
 \r
     //==============================================================================\r
index f0d59a5183c459315e96ec450a29d6c0aa0ef8f5..1da30c694f7859be8c8d6b6e083a73f724192188 100644 (file)
@@ -62,17 +62,6 @@ public:
         return "CODEBLOCKS_UNKNOWN_OS";\r
     }\r
 \r
-    //==============================================================================\r
-    static String getTargetFolderName (CodeBlocksOS os)\r
-    {\r
-        if (os == windowsTarget)  return "CodeBlocksWindows";\r
-        if (os == linuxTarget)    return "CodeBlocksLinux";\r
-\r
-        // currently no other OSes supported by Codeblocks exporter!\r
-        jassertfalse;\r
-        return "CodeBlocksUnknownOS";\r
-    }\r
-\r
     //==============================================================================\r
     static CodeBlocksProjectExporter* createForSettings (Project& project, const ValueTree& settings)\r
     {\r
@@ -93,7 +82,7 @@ public:
     {\r
         name = getName (os);\r
 \r
-        targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderName (os));\r
+        targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderForExporter (getValueTreeTypeName (os)));\r
 \r
         if (isWindows())\r
             targetPlatformValue.referTo (settings, Ids::codeBlocksWindowsTarget, getUndoManager());\r
@@ -192,19 +181,7 @@ public:
     }\r
 \r
     //==============================================================================\r
-    void initialiseDependencyPathValues() override\r
-    {\r
-        auto pathOS = isLinux() ? TargetOS::linux\r
-                                : TargetOS::windows;\r
-\r
-        vst3Path.referTo (Value (new DependencyPathValueSource (getSetting (Ids::vst3Folder), Ids::vst3Path, pathOS)));\r
-\r
-        if (! isLinux())\r
-        {\r
-            aaxPath.referTo  (Value (new DependencyPathValueSource (getSetting (Ids::aaxFolder), Ids::aaxPath, pathOS)));\r
-            rtasPath.referTo (Value (new DependencyPathValueSource (getSetting (Ids::rtasFolder), Ids::rtasPath, pathOS)));\r
-        }\r
-    }\r
+    void initialiseDependencyPathValues() override  {}\r
 \r
 private:\r
     ValueWithDefault targetPlatformValue;\r
@@ -305,7 +282,6 @@ private:
                     case pluginBundle:\r
                         switch (type)\r
                         {\r
-                            case VST3PlugIn:    return ".vst3";\r
                             case VSTPlugIn:     return ".so";\r
                             default:            break;\r
                         }\r
@@ -322,8 +298,7 @@ private:
 \r
         bool isDynamicLibrary() const\r
         {\r
-            return (type == DynamicLibrary || type == VST3PlugIn\r
-                     || type == VSTPlugIn || type == AAXPlugIn);\r
+            return (type == DynamicLibrary || type == VSTPlugIn);\r
         }\r
 \r
         const CodeBlocksProjectExporter& exporter;\r
@@ -546,7 +521,6 @@ private:
                 return 2;\r
             case ProjectType::Target::DynamicLibrary:\r
             case ProjectType::Target::VSTPlugIn:\r
-            case ProjectType::Target::VST3PlugIn:\r
                 return 3;\r
             default:\r
                 break;\r
@@ -595,8 +569,7 @@ private:
 \r
             if (isLinux())\r
             {\r
-                bool keepPrefix = (target.type == ProjectType::Target::VSTPlugIn || target.type == ProjectType::Target::VST3PlugIn\r
-                                || target.type == ProjectType::Target::AAXPlugIn || target.type == ProjectType::Target::RTASPlugIn);\r
+                bool keepPrefix = (target.type == ProjectType::Target::VSTPlugIn);\r
 \r
                 output->setAttribute ("prefix_auto", keepPrefix ? 0 : 1);\r
             }\r
index e8033ded7bf1a661315cc450a5e89db4d2ad8ed2..6449d1cd4400a0c9dd5b6d7210d8befef8ce7840 100644 (file)
@@ -31,7 +31,7 @@
 class MSVCProjectExporterBase   : public ProjectExporter\r
 {\r
 public:\r
-    MSVCProjectExporterBase (Project& p, const ValueTree& t, const char* const folderName)\r
+    MSVCProjectExporterBase (Project& p, const ValueTree& t, String folderName)\r
         : ProjectExporter (p, t),\r
           IPPLibraryValue       (settings, Ids::IPPLibrary,                   getUndoManager()),\r
           platformToolsetValue  (settings, Ids::toolset,                      getUndoManager()),\r
@@ -1058,16 +1058,14 @@ public:
                 RelativePath bundleScript  = aaxSDK.getChildFile ("Utilities").getChildFile ("CreatePackage.bat");\r
                 RelativePath iconFilePath  = getAAXIconFile();\r
 \r
-                auto is64Bit = (config.config [Ids::winArchitecture] == "x64");\r
-\r
                 auto outputFilename = config.getOutputFilename (".aaxplugin", true);\r
                 auto bundleDir      = getOwner().getOutDirFile (config, outputFilename);\r
                 auto bundleContents = bundleDir + "\\Contents";\r
-                auto macOSDir       = bundleContents + String ("\\") + (is64Bit ? "x64" : "Win32");\r
-                auto executable     = macOSDir + String ("\\") + outputFilename;\r
+                auto archDir        = bundleContents + String ("\\") + (config.is64Bit() ? "x64" : "Win32");\r
+                auto executable     = archDir + String ("\\") + outputFilename;\r
 \r
                 auto pkgScript = String ("copy /Y ") + getOutputFilePath (config).quoted() + String (" ") + executable.quoted() + String ("\r\ncall ")\r
-                                     + createRebasedPath (bundleScript) + String (" ") + macOSDir.quoted() + String (" ") + createRebasedPath (iconFilePath);\r
+                                     + createRebasedPath (bundleScript) + String (" ") + archDir.quoted() + String (" ") + createRebasedPath (iconFilePath);\r
 \r
                 if (config.isPluginBinaryCopyStepEnabled())\r
                     return pkgScript + "\r\n" + "xcopy " + bundleDir.quoted() + " "\r
@@ -1093,12 +1091,11 @@ public:
             {\r
                 String script;\r
 \r
-                bool is64Bit = (config.config [Ids::winArchitecture] == "x64");\r
                 auto bundleDir      = getOwner().getOutDirFile (config, config.getOutputFilename (".aaxplugin", false));\r
                 auto bundleContents = bundleDir + "\\Contents";\r
-                auto macOSDir       = bundleContents + String ("\\") + (is64Bit ? "x64" : "Win32");\r
+                auto archDir        = bundleContents + String ("\\") + (config.is64Bit() ? "x64" : "Win32");\r
 \r
-                for (auto& folder : StringArray { bundleDir, bundleContents, macOSDir })\r
+                for (auto& folder : StringArray { bundleDir, bundleContents, archDir })\r
                     script += String ("if not exist \"") + folder + String ("\" mkdir \"") + folder + String ("\"\r\n");\r
 \r
                 return script;\r
@@ -1810,7 +1807,7 @@ class MSVCProjectExporterVC2013  : public MSVCProjectExporterBase
 {\r
 public:\r
     MSVCProjectExporterVC2013 (Project& p, const ValueTree& t)\r
-        : MSVCProjectExporterBase (p, t, "VisualStudio2013")\r
+        : MSVCProjectExporterBase (p, t, getTargetFolderForExporter (getValueTreeTypeName()))\r
     {\r
         name = getName();\r
 \r
@@ -1856,7 +1853,7 @@ class MSVCProjectExporterVC2015  : public MSVCProjectExporterBase
 {\r
 public:\r
     MSVCProjectExporterVC2015 (Project& p, const ValueTree& t)\r
-        : MSVCProjectExporterBase (p, t, "VisualStudio2015")\r
+        : MSVCProjectExporterBase (p, t, getTargetFolderForExporter (getValueTreeTypeName()))\r
     {\r
         name = getName();\r
 \r
@@ -1901,7 +1898,7 @@ class MSVCProjectExporterVC2017  : public MSVCProjectExporterBase
 {\r
 public:\r
     MSVCProjectExporterVC2017 (Project& p, const ValueTree& t)\r
-        : MSVCProjectExporterBase (p, t, "VisualStudio2017")\r
+        : MSVCProjectExporterBase (p, t, getTargetFolderForExporter (getValueTreeTypeName()))\r
     {\r
         name = getName();\r
 \r
index e4e42251c4d6a578aed145dfc11045c6f25d7240..3ea5f6bce93a37a609ba4b5cb5b56cb1b64ec038 100644 (file)
@@ -180,7 +180,6 @@ public:
             {\r
                 case VSTPlugIn:\r
                 case DynamicLibrary:        return ".so";\r
-                case VST3PlugIn:            return ".vst3";\r
                 case SharedCodeTarget:\r
                 case StaticLibrary:         return ".a";\r
                 default:                    break;\r
@@ -328,7 +327,7 @@ public:
     {\r
         name = getNameLinux();\r
 \r
-        targetLocationValue.setDefault (getDefaultBuildsRootFolder() + "LinuxMakefile");\r
+        targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderForExporter (getValueTreeTypeName()));\r
     }\r
 \r
     //==============================================================================\r
@@ -421,12 +420,7 @@ public:
     }\r
 \r
     //==============================================================================\r
-    void initialiseDependencyPathValues() override\r
-    {\r
-        vst3Path.referTo (Value (new DependencyPathValueSource (getSetting (Ids::vst3Folder),\r
-                                                                Ids::vst3Path,\r
-                                                                TargetOS::linux)));\r
-    }\r
+    void initialiseDependencyPathValues() override  {}\r
 \r
 private:\r
     ValueWithDefault extraPkgConfigValue;\r
index 0b29b1a2995f41314d3cd48eb19b89371591e4e0..822711aa8eb20f666e7d2b70c58561eb631b182b 100644 (file)
@@ -89,7 +89,7 @@ public:
     {\r
         name = iOS ? getNameiOS() : getNameMac();\r
 \r
-        targetLocationValue.setDefault (getDefaultBuildsRootFolder() + (iOS ? "iOS" : "MacOSX"));\r
+        targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderForExporter (getValueTreeTypeName (isIOS)));\r
     }\r
 \r
     static XcodeProjectExporter* createForSettings (Project& project, const ValueTree& settings)\r
@@ -129,6 +129,9 @@ public:
     bool isPushNotificationsEnabled() const          { return iosPushNotificationsValue.get(); }\r
     bool isAppGroupsEnabled() const                  { return iosAppGroupsValue.get(); }\r
     bool isiCloudPermissionsEnabled() const          { return iCloudPermissionsValue.get(); }\r
+    bool isFileSharingEnabled() const                { return uiFileSharingEnabledValue.get(); }\r
+    bool isDocumentBrowserEnabled() const            { return uiSupportsDocumentBrowserValue.get(); }\r
+    bool isStatusBarHidden() const                   { return uiStatusBarHiddenValue.get(); }\r
 \r
     String getIosDevelopmentTeamIDString() const     { return iosDevelopmentTeamIDValue.get(); }\r
     String getAppGroupIdString() const               { return iosAppGroupsIDValue.get(); }\r
@@ -412,7 +415,7 @@ protected:
         XcodeBuildConfiguration (Project& p, const ValueTree& t, const bool isIOS, const ProjectExporter& e)\r
             : BuildConfiguration (p, t, e),\r
               iOS (isIOS),\r
-              osxSDKVersion                (config, Ids::osxSDK,                       getUndoManager(), String (osxVersionDefault) + " SDK"),\r
+              osxSDKVersion                (config, Ids::osxSDK,                       getUndoManager()),\r
               osxDeploymentTarget          (config, Ids::osxCompatibility,             getUndoManager(), String (osxVersionDefault) + " SDK"),\r
               iosDeploymentTarget          (config, Ids::iosCompatibility,             getUndoManager(), iosVersionDefault),\r
               osxArchitecture              (config, Ids::osxArchitecture,              getUndoManager(), osxArch_Default),\r
@@ -465,7 +468,8 @@ protected:
                 }\r
 \r
                 props.add (new ChoicePropertyComponent (osxSDKVersion, "OSX Base SDK Version", sdkVersionNames, versionValues),\r
-                           "The version of OSX to link against in the Xcode build.");\r
+                           "The version of OSX to link against in the Xcode build. If \"Default\" is selected then the field will be left "\r
+                           "empty and the Xcode default will be used.");\r
 \r
                 props.add (new ChoicePropertyComponent (osxDeploymentTarget, "OSX Deployment Target", osxVersionNames, versionValues),\r
                            "The minimum version of OSX that the target binary will be compatible with.");\r
@@ -1341,13 +1345,13 @@ public:
                 }\r
             }\r
 \r
-            if (owner.settings [Ids::UIFileSharingEnabled] && type != AudioUnitv3PlugIn)\r
+            if (owner.isFileSharingEnabled() && type != AudioUnitv3PlugIn)\r
                 addPlistDictionaryKeyBool (dict, "UIFileSharingEnabled", true);\r
 \r
-            if (owner.settings [Ids::UISupportsDocumentBrowser])\r
+            if (owner.isDocumentBrowserEnabled())\r
                 addPlistDictionaryKeyBool (dict, "UISupportsDocumentBrowser", true);\r
 \r
-            if (owner.settings [Ids::UIStatusBarHidden] && type != AudioUnitv3PlugIn)\r
+            if (owner.isStatusBarHidden() && type != AudioUnitv3PlugIn)\r
                 addPlistDictionaryKeyBool (dict, "UIStatusBarHidden", true);\r
 \r
             if (owner.iOS)\r
@@ -1515,7 +1519,7 @@ public:
             addPlistDictionaryKey (dict, "description", owner.project.getPluginDescriptionString());\r
             addPlistDictionaryKey (dict, "factoryFunction", owner.project.getPluginAUExportPrefixString() + "Factory");\r
             addPlistDictionaryKey (dict, "manufacturer", pluginManufacturerCode);\r
-            addPlistDictionaryKey (dict, "type", owner.project.getAUMainTypeCode());\r
+            addPlistDictionaryKey (dict, "type", owner.project.getAUMainTypeString().removeCharacters ("'"));\r
             addPlistDictionaryKey (dict, "subtype", pluginSubType);\r
             addPlistDictionaryKeyInt (dict, "version", owner.project.getVersionAsHexInteger());\r
 \r
@@ -1550,7 +1554,7 @@ public:
             addPlistDictionaryKey (componentDict, "description", owner.project.getPluginDescriptionString());\r
             addPlistDictionaryKey (componentDict, "factoryFunction",owner.project. getPluginAUExportPrefixString() + "FactoryAUv3");\r
             addPlistDictionaryKey (componentDict, "manufacturer", owner.project.getPluginManufacturerCodeString().substring (0, 4));\r
-            addPlistDictionaryKey (componentDict, "type", owner.project.getAUMainTypeCode());\r
+            addPlistDictionaryKey (componentDict, "type", owner.project.getAUMainTypeString().removeCharacters ("'"));\r
             addPlistDictionaryKey (componentDict, "subtype", owner.project.getPluginCodeString().substring (0, 4));\r
             addPlistDictionaryKeyInt (componentDict, "version", owner.project.getVersionAsHexInteger());\r
             addPlistDictionaryKeyBool (componentDict, "sandboxSafe", true);\r
@@ -1656,7 +1660,7 @@ public:
 \r
         String getOSXDeploymentTarget (const XcodeBuildConfiguration& config, String* sdkRoot = nullptr) const\r
         {\r
-            auto sdk = config.getOSXSDKVersionString() + " SDK";\r
+            auto sdk = config.getOSXSDKVersionString();\r
             auto sdkCompat = config.getOSXDeploymentTargetString();\r
 \r
             // The AUv3 target always needs to be at least 10.11\r
@@ -1668,8 +1672,8 @@ public:
 \r
             for (int ver = oldestAllowedDeploymentTarget; ver <= currentSDKVersion; ++ver)\r
             {\r
-                if (sdk == getSDKName (ver) && sdkRoot != nullptr) *sdkRoot = String ("macosx10." + String (ver));\r
-                if (sdkCompat == getSDKName (ver))   deploymentTarget = "10." + String (ver);\r
+                if (sdk.isNotEmpty() && (sdk == getSDKName (ver) && sdkRoot != nullptr)) *sdkRoot = String ("macosx10." + String (ver));\r
+                if (sdkCompat == getSDKName (ver))                                       deploymentTarget = "10." + String (ver);\r
             }\r
 \r
             return deploymentTarget;\r
@@ -1845,8 +1849,15 @@ private:
             topLevelGroupIDs.add (addEntitlementsFile (entitlements));\r
 \r
         for (auto& group : getAllGroups())\r
+        {\r
             if (group.getNumChildren() > 0)\r
-                topLevelGroupIDs.add (addProjectItem (group));\r
+            {\r
+                auto groupID = addProjectItem (group);\r
+\r
+                if (groupID.isNotEmpty())\r
+                    topLevelGroupIDs.add (groupID);\r
+            }\r
+        }\r
     }\r
 \r
     void addExtraGroupsToProject (StringArray& topLevelGroupIDs) const\r
@@ -2669,12 +2680,17 @@ private:
             StringArray childIDs;\r
             for (int i = 0; i < projectItem.getNumChildren(); ++i)\r
             {\r
-                auto childID = addProjectItem (projectItem.getChild(i));\r
+                auto child = projectItem.getChild (i);\r
+\r
+                auto childID = addProjectItem (child);\r
 \r
-                if (childID.isNotEmpty())\r
+                if (childID.isNotEmpty() && ! child.shouldBeAddedToXcodeResources())\r
                     childIDs.add (childID);\r
             }\r
 \r
+            if (childIDs.isEmpty())\r
+                return {};\r
+\r
             return addGroup (projectItem, childIDs);\r
         }\r
 \r
index fdd7cb503e096b2310d8b0d2377d74f0aa9f9f45..d4656f1ab0bec1acec6dfb0ea4aab2eb14d5df9b 100644 (file)
@@ -96,6 +96,16 @@ StringArray ProjectExporter::getExporterNames()
     return s;\r
 }\r
 \r
+StringArray ProjectExporter::getExporterValueTreeNames()\r
+{\r
+    StringArray s;\r
+\r
+    for (auto& n : getExporterNames())\r
+        s.add (getValueTreeNameForExporter (n));\r
+\r
+    return s;\r
+}\r
+\r
 String ProjectExporter::getValueTreeNameForExporter (const String& exporterName)\r
 {\r
     if (exporterName == XcodeProjectExporter::getNameMac())\r
@@ -131,6 +141,22 @@ String ProjectExporter::getValueTreeNameForExporter (const String& exporterName)
     return {};\r
 }\r
 \r
+String ProjectExporter::getTargetFolderForExporter (const String& exporterValueTreeName)\r
+{\r
+    if (exporterValueTreeName == "XCODE_MAC")             return "MacOSX";\r
+    if (exporterValueTreeName == "XCODE_IPHONE")          return "iOS";\r
+    if (exporterValueTreeName == "VS2017")                return "VisualStudio2017";\r
+    if (exporterValueTreeName == "VS2015")                return "VisualStudio2015";\r
+    if (exporterValueTreeName == "VS2013")                return "VisualStudio2013";\r
+    if (exporterValueTreeName == "LINUX_MAKE")            return "LinuxMakefile";\r
+    if (exporterValueTreeName == "ANDROIDSTUDIO")         return "Android";\r
+    if (exporterValueTreeName == "CODEBLOCKS_WINDOWS")    return "CodeBlocksWindows";\r
+    if (exporterValueTreeName == "CODEBLOCKS_LINUX")      return "CodeBlocksLinux";\r
+    if (exporterValueTreeName == "CLION")                 return "CLion";\r
+\r
+    return {};\r
+}\r
+\r
 StringArray ProjectExporter::getAllDefaultBuildsFolders()\r
 {\r
     StringArray folders;\r
index ba02d5525bbac8e60ff68c0739efcc8d0fcd93b3..c8332d4837bf5eb95c43b6112ad5fc3993a0109f 100644 (file)
@@ -59,8 +59,10 @@ public:
     };\r
 \r
     static StringArray getExporterNames();\r
+    static StringArray getExporterValueTreeNames();\r
     static Array<ExporterTypeInfo> getExporterTypes();\r
     static String getValueTreeNameForExporter (const String& exporterName);\r
+    static String getTargetFolderForExporter (const String& exporterValueTreeName);\r
     static StringArray getAllDefaultBuildsFolders();\r
 \r
     static ProjectExporter* createNewExporter (Project&, const int index);\r
index 1e077f16d3ef022539e58624165e76beb2c98aa0..d5075906a8febe8404f2f1b2900c84b8377c161a 100644 (file)
@@ -100,14 +100,15 @@ void ProjectSaver::writePluginCharacteristicsFile()
     flags.set ("JucePlugin_VersionCode",                 project.getVersionAsHex());\r
     flags.set ("JucePlugin_VersionString",               toStringLiteral (project.getVersionString()));\r
     flags.set ("JucePlugin_VSTUniqueID",                 "JucePlugin_PluginCode");\r
-    flags.set ("JucePlugin_VSTCategory",                 project.getPluginVSTCategoryString());\r
+    flags.set ("JucePlugin_VSTCategory",                 project.getVSTCategoryString());\r
+    flags.set ("JucePlugin_Vst3Category",                toStringLiteral (project.getVST3CategoryString()));\r
     flags.set ("JucePlugin_AUMainType",                  project.getAUMainTypeString());\r
     flags.set ("JucePlugin_AUSubType",                   "JucePlugin_PluginCode");\r
     flags.set ("JucePlugin_AUExportPrefix",              project.getPluginAUExportPrefixString());\r
     flags.set ("JucePlugin_AUExportPrefixQuoted",        toStringLiteral (project.getPluginAUExportPrefixString()));\r
     flags.set ("JucePlugin_AUManufacturerCode",          "JucePlugin_ManufacturerCode");\r
     flags.set ("JucePlugin_CFBundleIdentifier",          project.getBundleIdentifierString());\r
-    flags.set ("JucePlugin_RTASCategory",                project.getPluginRTASCategoryCode());\r
+    flags.set ("JucePlugin_RTASCategory",                String (project.getRTASCategory()));\r
     flags.set ("JucePlugin_RTASManufacturerCode",        "JucePlugin_ManufacturerCode");\r
     flags.set ("JucePlugin_RTASProductId",               "JucePlugin_PluginCode");\r
     flags.set ("JucePlugin_RTASDisableBypass",           boolToString (project.isPluginRTASBypassDisabled()));\r
@@ -115,7 +116,7 @@ void ProjectSaver::writePluginCharacteristicsFile()
     flags.set ("JucePlugin_AAXIdentifier",               project.getAAXIdentifierString());\r
     flags.set ("JucePlugin_AAXManufacturerCode",         "JucePlugin_ManufacturerCode");\r
     flags.set ("JucePlugin_AAXProductId",                "JucePlugin_PluginCode");\r
-    flags.set ("JucePlugin_AAXCategory",                 project.getPluginAAXCategoryString());\r
+    flags.set ("JucePlugin_AAXCategory",                 String (project.getAAXCategory()));\r
     flags.set ("JucePlugin_AAXDisableBypass",            boolToString (project.isPluginAAXBypassDisabled()));\r
     flags.set ("JucePlugin_AAXDisableMultiMono",         boolToString (project.isPluginAAXMultiMonoDisabled()));\r
     flags.set ("JucePlugin_IAAType",                     toCharLiteral (project.getIAATypeCode()));\r
@@ -127,8 +128,8 @@ void ProjectSaver::writePluginCharacteristicsFile()
 \r
         if (plugInChannelConfig.isNotEmpty())\r
         {\r
-            flags.set ("JucePlugin_MaxNumInputChannels",         String (countMaxPluginChannels (plugInChannelConfig, true)));\r
-            flags.set ("JucePlugin_MaxNumOutputChannels",        String (countMaxPluginChannels (plugInChannelConfig, false)));\r
+            flags.set ("JucePlugin_MaxNumInputChannels",            String (countMaxPluginChannels (plugInChannelConfig, true)));\r
+            flags.set ("JucePlugin_MaxNumOutputChannels",           String (countMaxPluginChannels (plugInChannelConfig, false)));\r
             flags.set ("JucePlugin_PreferredChannelConfigurations", plugInChannelConfig);\r
         }\r
     }\r
index dbc53241de1d6cddd32364ee3f0f1f9888b50ce1..3f5b73174bab583a00c1c53e597a415bc37e7d55 100644 (file)
@@ -543,7 +543,7 @@ private:
             out << newLine;\r
         }\r
 \r
-        if (hasBinaryData && project.shouldIncludeBinaryInAppConfig())\r
+        if (hasBinaryData && project.shouldIncludeBinaryInJuceHeader())\r
             out << CodeHelpers::createIncludeStatement (project.getBinaryDataHeaderFile(), appConfigFile) << newLine;\r
 \r
         out << newLine\r
index e45bb188f6e13df2de25d6c4544a6b1aa55123ac..b4d52dfccd15f6cf0d71cd1bd7ab8d39bfc16603 100644 (file)
@@ -142,15 +142,22 @@ Result ResourceFile::writeHeader (MemoryOutputStream& header)
         }\r
     }\r
 \r
-    header << "    // Points to the start of a list of resource names." << newLine\r
-           << "    extern const char* namedResourceList[];" << newLine\r
+    header << "    // Number of elements in the namedResourceList and originalFileNames arrays."                             << newLine\r
+           << "    const int namedResourceListSize = " << files.size() <<  ";"                                               << newLine\r
            << newLine\r
-           << "    // Number of elements in the namedResourceList array." << newLine\r
-           << "    const int namedResourceListSize = " << files.size() <<  ";" << newLine\r
+           << "    // Points to the start of a list of resource names."                                                      << newLine\r
+           << "    extern const char* namedResourceList[];"                                                                  << newLine\r
            << newLine\r
-           << "    // If you provide the name of one of the binary resource variables above, this function will" << newLine\r
-           << "    // return the corresponding data and its size (or a null pointer if the name isn't found)." << newLine\r
-           << "    const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes) throw();" << newLine\r
+           << "    // Points to the start of a list of resource filenames."                                                  << newLine\r
+           << "    extern const char* originalFilenames[];"                                                                  << newLine\r
+           << newLine\r
+           << "    // If you provide the name of one of the binary resource variables above, this function will"             << newLine\r
+           << "    // return the corresponding data and its size (or a null pointer if the name isn't found)."               << newLine\r
+           << "    const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes) noexcept;"              << newLine\r
+           << newLine\r
+           << "    // If you provide the name of one of the binary resource variables above, this function will"             << newLine\r
+           << "    // return the corresponding original, non-mangled filename (or a null pointer if the name isn't found)."  << newLine\r
+           << "    const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8) noexcept;"                    << newLine\r
            << "}" << newLine;\r
 \r
     return Result::ok();\r
@@ -215,35 +222,53 @@ Result ResourceFile::writeCpp (MemoryOutputStream& cpp, const File& headerFile,
 \r
         cpp << newLine\r
             << newLine\r
-            << "const char* getNamedResource (const char*, int&) throw();" << newLine\r
-            << "const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw()" << newLine\r
+            << "const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) noexcept" << newLine\r
             << "{" << newLine;\r
 \r
         StringArray returnCodes;\r
-        for (int j = 0; j < files.size(); ++j)\r
+        for (auto& file : files)\r
         {\r
-            auto& file = files.getReference(j);\r
             auto dataSize = file.getSize();\r
-            returnCodes.add ("numBytes = " + String (dataSize) + "; return " + variableNames[j] + ";");\r
+            returnCodes.add ("numBytes = " + String (dataSize) + "; return " + variableNames[files.indexOf (file)] + ";");\r
         }\r
 \r
         CodeHelpers::createStringMatcher (cpp, "resourceNameUTF8", variableNames, returnCodes, 4);\r
 \r
         cpp << "    numBytes = 0;" << newLine\r
-            << "    return 0;" << newLine\r
+            << "    return nullptr;" << newLine\r
             << "}" << newLine\r
-            << newLine\r
-            << "const char* namedResourceList[] =" << newLine\r
+            << newLine;\r
+\r
+        cpp << "const char* namedResourceList[] =" << newLine\r
             << "{" << newLine;\r
 \r
         for (int j = 0; j < files.size(); ++j)\r
             cpp << "    " << variableNames[j].quoted() << (j < files.size() - 1 ? "," : "") << newLine;\r
 \r
-        cpp << "};" << newLine;\r
+        cpp << "};" << newLine << newLine;\r
+\r
+        cpp << "const char* originalFilenames[] =" << newLine\r
+            << "{" << newLine;\r
+\r
+        for (auto& f : files)\r
+            cpp << "    " << f.getFileName().quoted() << (files.indexOf (f) < files.size() - 1 ? "," : "") << newLine;\r
+\r
+        cpp << "};" << newLine << newLine;\r
+\r
+        cpp << "const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8) noexcept"                << newLine\r
+            << "{"                                                                                                   << newLine\r
+            << "    for (unsigned int i = 0; i < (sizeof (namedResourceList) / sizeof (namedResourceList[0])); ++i)" << newLine\r
+            << "    {"                                                                                               << newLine\r
+            << "        if (namedResourceList[i] == resourceNameUTF8)"                                               << newLine\r
+            << "            return originalFilenames[i];"                                                            << newLine\r
+            << "    }"                                                                                               << newLine\r
+            <<                                                                                                          newLine\r
+            << "    return nullptr;"                                                                                 << newLine\r
+            << "}"                                                                                                   << newLine\r
+            <<                                                                                                          newLine;\r
     }\r
 \r
-    cpp << newLine\r
-        << "}" << newLine;\r
+    cpp << "}" << newLine;\r
 \r
     return Result::ok();\r
 }\r
index adc74d7f0462be3aba55484740379793c64a66cd..542e8aa6a48ca3ed8cb8d3724a3e46f673020b3e 100644 (file)
@@ -202,8 +202,8 @@ void StoredSettings::checkJUCEPaths()
     auto moduleFolder = projectDefaults.getProperty (Ids::defaultJuceModulePath).toString();\r
     auto juceFolder = projectDefaults.getProperty (Ids::jucePath).toString();\r
 \r
-    auto validModuleFolder = isGlobalPathValid ({}, Ids::defaultJuceModulePath, moduleFolder);\r
-    auto validJuceFolder = isGlobalPathValid ({}, Ids::jucePath, juceFolder);\r
+    auto validModuleFolder = moduleFolder.isNotEmpty() && isGlobalPathValid ({}, Ids::defaultJuceModulePath, moduleFolder);\r
+    auto validJuceFolder = juceFolder.isNotEmpty() && isGlobalPathValid ({}, Ids::jucePath, juceFolder);\r
 \r
     if (validModuleFolder && ! validJuceFolder)\r
         projectDefaults.getPropertyAsValue (Ids::jucePath, nullptr) = File (moduleFolder).getParentDirectory().getFullPathName();\r
index 73c14677e88b9a3731207611d9c4ea29750b0701..1a377cf9bde87f4fc36262eda691ea19f9b1da2a 100644 (file)
 #include "../../Application/jucer_Headers.h"\r
 \r
 //==============================================================================\r
-const char* getLineEnding()  { return "\r\n"; }\r
-\r
 String joinLinesIntoSourceFile (StringArray& lines)\r
 {\r
     while (lines.size() > 10 && lines [lines.size() - 1].isEmpty())\r
         lines.remove (lines.size() - 1);\r
 \r
-    return lines.joinIntoString (getLineEnding()) + getLineEnding();\r
+    return lines.joinIntoString (getPreferredLinefeed()) + getPreferredLinefeed();\r
 }\r
 \r
 String trimCommentCharsFromStartOfLine (const String& line)\r
@@ -48,7 +46,7 @@ String createAlphaNumericUID()
     const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";\r
     Random r;\r
 \r
-    uid << chars [r.nextInt (52)]; // make sure the first character is always a letter\r
+    uid << chars[r.nextInt (52)]; // make sure the first character is always a letter\r
 \r
     for (int i = 5; --i >= 0;)\r
     {\r
@@ -66,7 +64,7 @@ String hexString8Digits (int value)
 \r
 String createGUID (const String& seed)\r
 {\r
-    const String hex (MD5 ((seed + "_guidsalt").toUTF8()).toHexString().toUpperCase());\r
+    auto hex = MD5 ((seed + "_guidsalt").toUTF8()).toHexString().toUpperCase();\r
 \r
     return "{" + hex.substring (0, 8)\r
          + "-" + hex.substring (8, 12)\r
@@ -292,7 +290,7 @@ bool fileNeedsCppSyntaxHighlighting (const File& file)
 }\r
 \r
 //==============================================================================\r
-bool isJUCEModule (const String& moduleID) noexcept\r
+StringArray getJUCEModules() noexcept\r
 {\r
     static StringArray juceModuleIds =\r
     {\r
@@ -319,40 +317,12 @@ bool isJUCEModule (const String& moduleID) noexcept
         "juce_video"\r
     };\r
 \r
-    return juceModuleIds.contains (moduleID);\r
-}\r
-\r
-bool isValidExporterName (const String& exporterName) noexcept\r
-{\r
-    static StringArray validExporters =\r
-    {\r
-        "XCODE_MAC",\r
-        "XCODE_IPHONE",\r
-        "VS2013",\r
-        "VS2015",\r
-        "VS2017",\r
-        "LINUX_MAKE",\r
-        "ANDROIDSTUDIO",\r
-        "CODEBLOCKS_WINDOWS",\r
-        "CODEBLOCKS_LINUX"\r
-    };\r
-\r
-    return validExporters.contains (exporterName);\r
+    return juceModuleIds;\r
 }\r
 \r
-String getTargetFolderForExporter (const String& exporterName) noexcept\r
+bool isJUCEModule (const String& moduleID) noexcept\r
 {\r
-    if (exporterName == "XCODE_MAC")             return "MacOSX";\r
-    if (exporterName == "XCODE_IPHONE")          return "iOS";\r
-    if (exporterName == "VS2017")                return "VisualStudio2017";\r
-    if (exporterName == "VS2015")                return "VisualStudio2015";\r
-    if (exporterName == "VS2013")                return "MacOVisualStudio2015SX";\r
-    if (exporterName == "LINUX_MAKE")            return "LinuxMakefile";\r
-    if (exporterName == "ANDROIDSTUDIO")         return "Android";\r
-    if (exporterName == "CODEBLOCKS_WINDOWS")    return "CodeBlocksWindows";\r
-    if (exporterName == "CODEBLOCKS_LINUX")      return "CodeBlocksLinux";\r
-\r
-    return {};\r
+    return getJUCEModules().contains (moduleID);\r
 }\r
 \r
 StringArray getModulesRequiredForConsole() noexcept\r
@@ -403,16 +373,6 @@ bool isPIPFile (const File& file) noexcept
     return false;\r
 }\r
 \r
-File getJUCEExamplesDirectoryPathFromGlobal() noexcept\r
-{\r
-    auto globalPath = getAppSettings().getStoredPath (Ids::jucePath).toString();\r
-\r
-    if (globalPath.isNotEmpty())\r
-        return File (getAppSettings().getStoredPath (Ids::jucePath).toString()).getChildFile ("examples");\r
-\r
-    return {};\r
-}\r
-\r
 bool isValidJUCEExamplesDirectory (const File& directory) noexcept\r
 {\r
     if (! directory.exists() || ! directory.isDirectory() || ! directory.containsSubDirectories())\r
index 253e1618e2f9fc79af1c33f9c1bd6ecd4e778915..28da5491036bba2de58fdc4739af0551a7025110 100644 (file)
@@ -28,7 +28,7 @@
 \r
 \r
 //==============================================================================\r
-const char* getLineEnding();\r
+const char* getPreferredLinefeed();\r
 String joinLinesIntoSourceFile (StringArray& lines);\r
 \r
 String trimCommentCharsFromStartOfLine (const String& line);\r
@@ -58,9 +58,8 @@ void addPlistDictionaryKeyInt (XmlElement* xml, const String& key, int value);
 \r
 bool fileNeedsCppSyntaxHighlighting (const File& file);\r
 \r
+StringArray getJUCEModules() noexcept;\r
 bool isJUCEModule (const String& moduleID) noexcept;\r
-bool isValidExporterName (const String& exporterName) noexcept;\r
-String getTargetFolderForExporter (const String& exporterName) noexcept;\r
 \r
 StringArray getModulesRequiredForConsole() noexcept;\r
 StringArray getModulesRequiredForComponent() noexcept;\r
@@ -68,7 +67,6 @@ StringArray getModulesRequiredForAudioProcessor() noexcept;
 \r
 bool isPIPFile (const File&) noexcept;\r
 \r
-File getJUCEExamplesDirectoryPathFromGlobal() noexcept;\r
 bool isValidJUCEExamplesDirectory (const File&) noexcept;\r
 \r
 //==============================================================================\r
@@ -96,7 +94,7 @@ struct PropertyListBuilder
              mainHelpText + " Use semi-colons or new-lines to separate multiple paths.");\r
     }\r
 \r
-    void addSearchPathProperty (const ValueWithDefault& value, const String& name, const String& mainHelpText)\r
+    void addSearchPathProperty (ValueWithDefault& value, const String& name, const String& mainHelpText)\r
     {\r
         add (new TextPropertyComponent (value, name, 16384, true),\r
              mainHelpText + " Use semi-colons or new-lines to separate multiple paths.");\r
index deeb2012e12241870e0a7d5ae1c2f0ac742a644a..6ae0c3ad89c44da36722eb4e8c2a7ab11c637d5b 100644 (file)
@@ -149,7 +149,6 @@ namespace Ids
     DECLARE_ID (enableIncrementalLinking);\r
     DECLARE_ID (bundleIdentifier);\r
     DECLARE_ID (aaxIdentifier);\r
-    DECLARE_ID (aaxCategory);\r
     DECLARE_ID (aaxFolder);\r
     DECLARE_ID (compile);\r
     DECLARE_ID (noWarnings);\r
@@ -243,7 +242,7 @@ namespace Ids
     DECLARE_ID (colour);\r
     DECLARE_ID (userNotes);\r
     DECLARE_ID (maxBinaryFileSize);\r
-    DECLARE_ID (includeBinaryInAppConfig);\r
+    DECLARE_ID (includeBinaryInJuceHeader);\r
     DECLARE_ID (binaryDataNamespace);\r
     DECLARE_ID (characterSet);\r
     DECLARE_ID (JUCERPROJECT);\r
@@ -289,6 +288,7 @@ namespace Ids
     DECLARE_ID (classDecl);\r
     DECLARE_ID (initialisers);\r
     DECLARE_ID (destructors);\r
+    DECLARE_ID (pluginFormats);\r
     DECLARE_ID (buildVST);\r
     DECLARE_ID (buildVST3);\r
     DECLARE_ID (buildAU);\r
@@ -303,12 +303,14 @@ namespace Ids
     DECLARE_ID (pluginManufacturerCode);\r
     DECLARE_ID (pluginCode);\r
     DECLARE_ID (pluginChannelConfigs);\r
+    DECLARE_ID (pluginCharacteristicsValue);\r
     DECLARE_ID (pluginIsSynth);\r
     DECLARE_ID (pluginWantsMidiIn);\r
     DECLARE_ID (pluginProducesMidiOut);\r
     DECLARE_ID (pluginIsMidiEffectPlugin);\r
     DECLARE_ID (pluginEditorRequiresKeys);\r
     DECLARE_ID (pluginVSTCategory);\r
+    DECLARE_ID (pluginVST3Category);\r
     DECLARE_ID (pluginAUExportPrefix);\r
     DECLARE_ID (pluginAUMainType);\r
     DECLARE_ID (pluginRTASCategory);\r
@@ -321,6 +323,9 @@ namespace Ids
     DECLARE_ID (website);\r
     DECLARE_ID (mainClass);\r
     DECLARE_ID (moduleFlags);\r
+    DECLARE_ID (buildEnabled);\r
+    DECLARE_ID (continuousRebuildEnabled);\r
+    DECLARE_ID (warningsEnabled);\r
 \r
     const Identifier ID ("id");\r
     const Identifier ID_uppercase ("ID");\r
index 2d45b1297b909a6b54bfe38c7c28d4a3e5adf50d..7256548a3f2f82ff3d421e75639d694852f089a6 100644 (file)
@@ -25,6 +25,7 @@
 */\r
 \r
 #include "../../Application/jucer_Headers.h"\r
+#include "../../ProjectSaving/jucer_ProjectExporter.h"\r
 #include "jucer_PIPGenerator.h"\r
 \r
 //==============================================================================\r
@@ -62,7 +63,7 @@ static void ensureSingleNewLineAfterIncludes (StringArray& lines)
     }\r
 }\r
 \r
-static String ensureCorrectWhitespace (const String& input)\r
+static String ensureCorrectWhitespace (StringRef input)\r
 {\r
     auto lines = StringArray::fromLines (input);\r
     ensureSingleNewLineAfterIncludes (lines);\r
@@ -85,6 +86,16 @@ static bool isJUCEExample (const File& pipFile)
     return false;\r
 }\r
 \r
+static bool isValidExporterName (StringRef exporterName)\r
+{\r
+    return ProjectExporter::getExporterValueTreeNames().contains (exporterName, true);\r
+}\r
+\r
+static bool isMobileExporter (const String& exporterName)\r
+{\r
+    return exporterName == "XCODE_IPHONE" || exporterName == "ANDROIDSTUDIO";\r
+}\r
+\r
 //==============================================================================\r
 PIPGenerator::PIPGenerator (const File& pip, const File& output)\r
     : pipFile (pip),\r
@@ -297,7 +308,26 @@ ValueTree PIPGenerator::createExporterChild (const String& exporterName)
 {\r
     ValueTree exporter (exporterName);\r
 \r
-    exporter.setProperty (Ids::targetFolder, "Builds/" + getTargetFolderForExporter (exporterName), nullptr);\r
+    exporter.setProperty (Ids::targetFolder, "Builds/" + ProjectExporter::getTargetFolderForExporter (exporterName), nullptr);\r
+\r
+    if (isMobileExporter (exporterName))\r
+    {\r
+        auto juceDir = getAppSettings().getStoredPath (Ids::jucePath).toString();\r
+\r
+        if (juceDir.isNotEmpty() && isValidJUCEExamplesDirectory (File (juceDir).getChildFile ("examples")))\r
+        {\r
+            auto assetsDirectoryPath = File (juceDir).getChildFile ("examples").getChildFile ("Assets").getFullPathName();\r
+\r
+            exporter.setProperty (exporterName == "XCODE_IPHONE" ? Ids::customXcodeResourceFolders\r
+                                                                 : Ids::androidExtraAssetsFolder,\r
+                                  assetsDirectoryPath, nullptr);\r
+        }\r
+        else\r
+        {\r
+            // invalid JUCE path\r
+            jassertfalse;\r
+        }\r
+    }\r
 \r
     {\r
         ValueTree configs (Ids::CONFIGURATIONS);\r
@@ -395,12 +425,12 @@ Result PIPGenerator::setProjectSettings (ValueTree& jucerTree)
 \r
     if (useLocalCopy && isJUCEExample (pipFile))\r
     {\r
-        auto examplesDirectory = getJUCEExamplesDirectoryPathFromGlobal();\r
+        auto juceDir = getAppSettings().getStoredPath (Ids::jucePath).toString();\r
 \r
-        if (isValidJUCEExamplesDirectory (examplesDirectory))\r
+        if (juceDir.isNotEmpty() && isValidJUCEExamplesDirectory (File (juceDir).getChildFile ("examples")))\r
         {\r
              defines += ((defines.isEmpty() ? "" : " ") + String ("PIP_JUCE_EXAMPLES_DIRECTORY=")\r
-                         + Base64::toBase64 (examplesDirectory.getFullPathName()));\r
+                         + Base64::toBase64 (File (juceDir).getChildFile ("examples").getFullPathName()));\r
         }\r
         else\r
         {\r
@@ -426,10 +456,11 @@ Result PIPGenerator::setProjectSettings (ValueTree& jucerTree)
     else if (type == "AudioProcessor")\r
     {\r
         jucerTree.setProperty (Ids::projectType, "audioplug", nullptr);\r
+        jucerTree.setProperty (Ids::pluginManufacturer, metadata[Ids::vendor], nullptr);\r
 \r
-        jucerTree.setProperty (Ids::buildVST,        false, nullptr);\r
+        jucerTree.setProperty (Ids::buildVST,        true, nullptr);\r
         jucerTree.setProperty (Ids::buildVST3,       false, nullptr);\r
-        jucerTree.setProperty (Ids::buildAU,         false, nullptr);\r
+        jucerTree.setProperty (Ids::buildAU,         true, nullptr);\r
         jucerTree.setProperty (Ids::buildAUv3,       false, nullptr);\r
         jucerTree.setProperty (Ids::buildRTAS,       false, nullptr);\r
         jucerTree.setProperty (Ids::buildAAX,        false, nullptr);\r
@@ -481,7 +512,7 @@ String PIPGenerator::getMainFileTextForType()
         mainTemplate = mainTemplate.replace ("%%project_version%%", metadata[Ids::version].toString());\r
 \r
         return ensureCorrectWhitespace (mainTemplate.replace ("%%startup%%", "mainWindow = new MainWindow (" + metadata[Ids::name].toString().quoted()\r
-                                                            + ", new " + metadata[Ids::mainClass].toString() + "());")\r
+                                                            + ", new " + metadata[Ids::mainClass].toString() + "(), *this);")\r
                                                     .replace ("%%shutdown%%", "mainWindow = nullptr;"));\r
     }\r
     else if (type == "AudioProcessor")\r
@@ -510,6 +541,9 @@ Array<File> PIPGenerator::replaceRelativeIncludesAndGetFilesToMove()
             auto path = line.fromFirstOccurrenceOf ("#include", false, false);\r
             path = path.removeCharacters ("\"").trim();\r
 \r
+            if (path.startsWith ("<") && path.endsWith (">"))\r
+                continue;\r
+\r
             auto file = pipFile.getParentDirectory().getChildFile (path);\r
             files.add (file);\r
 \r
index d85769efa4c516b7f217066cb808e772dad4c7b0..083da2df4280176fafd100c9159e04354b7c03f7 100644 (file)
@@ -37,6 +37,7 @@ public:
     //==============================================================================\r
     bool hasValidPIP() const noexcept                   { return ! metadata[Ids::name].toString().isEmpty(); }\r
     File getJucerFile() noexcept                        { return outputDirectory.getChildFile (metadata[Ids::name].toString() + ".jucer"); }\r
+    File getPIPFile() noexcept                          { return useLocalCopy ? outputDirectory.getChildFile ("Source").getChildFile (pipFile.getFileName()) : pipFile; }\r
 \r
     String getMainClassName() const noexcept            { return metadata[Ids::mainClass]; }\r
 \r
index f5dcb132a2f64bc64cc4ff0a5b996907f1c2e7f4..7338b22d8fc41968d30a284ec40374aec129a6f2 100644 (file)
@@ -32,7 +32,7 @@ class TextPropertyComponentWithEnablement    : public TextPropertyComponent,
                                                private Value::Listener\r
 {\r
 public:\r
-    TextPropertyComponentWithEnablement (const ValueWithDefault& valueToControl,\r
+    TextPropertyComponentWithEnablement (ValueWithDefault& valueToControl,\r
                                          ValueWithDefault valueToListenTo,\r
                                          const String& propertyName,\r
                                          int maxNumChars,\r
@@ -59,7 +59,7 @@ class ChoicePropertyComponentWithEnablement    : public ChoicePropertyComponent,
                                                  private Value::Listener\r
 {\r
 public:\r
-    ChoicePropertyComponentWithEnablement (const ValueWithDefault& valueToControl,\r
+    ChoicePropertyComponentWithEnablement (ValueWithDefault& valueToControl,\r
                                            ValueWithDefault valueToListenTo,\r
                                            const String& propertyName,\r
                                            const StringArray& choices,\r
index 8e7061ad39d1e833a7985d550ae819b4c7388c85..cb8194e183bc876908abd6fc8d8d6dd11e5a626f 100644 (file)
@@ -92,7 +92,7 @@ void JucerTreeViewBase::paintOpenCloseButton (Graphics& g, const Rectangle<float
     TreeViewItem::paintOpenCloseButton (g, area, getOwnerView()->findColour (defaultIconColourId), isMouseOver);\r
 }\r
 \r
-void JucerTreeViewBase::paintIcon (Graphics &g, Rectangle<float> area)\r
+void JucerTreeViewBase::paintIcon (Graphicsg, Rectangle<float> area)\r
 {\r
     g.setColour (getContentColour (true));\r
     getIcon().draw (g, area, isIconCrossedOut());\r
index 39a65b473d59f1c441e90cc244cf1e2bd30eeccb..b082483cd2ff85d7fc441a705adfd29a3b4b00e6 100644 (file)
@@ -187,7 +187,7 @@ struct NewProjectWizard
 \r
         for (int i = 0; i < mods.size(); ++i)\r
             if (const ModuleDescription* info = list.getModuleWithID (mods[i]))\r
-                project.getModules().addModule (info->moduleFolder, false, useGlobalPath);\r
+                project.getModules().addModule (info->moduleFolder, false, useGlobalPath, false);\r
     }\r
 \r
     void addExporters (Project& project, WizardComp& wizardComp)\r
index 82c20ee123ad51098377f4c3d2f7a81bbff1e8fe..f6fddc6db9c38195a49e1a7971f81e516a1ac1d2 100644 (file)
@@ -121,6 +121,14 @@ public:
     }\r
 \r
 private:\r
+    void clicked() override\r
+    {\r
+        StringPairArray data;\r
+        data.set ("label", getName());\r
+\r
+        Analytics::getInstance()->logEvent ("Start Page Button", data, ProjucerAnalyticsEvent::startPageEvent);\r
+    }\r
+\r
     ScopedPointer<Drawable> thumb, hoverBackground;\r
     String name, description;\r
 \r
index e1b70c628cca6cd3d1538b0762701123f4a60069..508e24c1f1fe40e89d83c92e769b45f29e292a71 100644 (file)
                                INSTALL_PATH = "/usr/bin";
                                MACOSX_DEPLOYMENT_TARGET = 10.10;
                                MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
-                               OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wstrict-aliasing -Wconversion -Wsign-compare -Woverloaded-virtual -Wextra-semi";
+                               OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -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 -Wno-ignored-qualifiers -Wunreachable-code";
                                PRODUCT_BUNDLE_IDENTIFIER = com.roli.UnitTestRunner;
                                SDKROOT_ppc = macosx10.5;
                                USE_HEADERMAP = NO; }; name = Debug; };
                                LLVM_LTO = YES;
                                MACOSX_DEPLOYMENT_TARGET = 10.10;
                                MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
-                               OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wstrict-aliasing -Wconversion -Wsign-compare -Woverloaded-virtual -Wextra-semi";
+                               OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -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 -Wno-ignored-qualifiers -Wunreachable-code";
                                PRODUCT_BUNDLE_IDENTIFIER = com.roli.UnitTestRunner;
                                SDKROOT_ppc = macosx10.5;
                                USE_HEADERMAP = NO; }; name = Release; };
index 2ed81a815e7660aaa7610ecddbf4aad6584daaeb..b59b8279377989c335688f14b9d0f177aa1afcca 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
index 4b25c8d0a62e6ac0216f43906b8da83ef32a2997..47e017ffddf19f8fa991fdc90ab507c4a906923d 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
index 7eebe7fc8c69cc45c7f1818540761560abe3121f..d15076fc5fbdd113a86164c0f8cf76c76f3a0a3b 100644 (file)
  //#define JUCE_JACK 0\r
 #endif\r
 \r
+#ifndef    JUCE_BELA\r
+ //#define JUCE_BELA 0\r
+#endif\r
+\r
 #ifndef    JUCE_USE_ANDROID_OBOE\r
  //#define JUCE_USE_ANDROID_OBOE 0\r
 #endif\r
index 261a3c3ea57a64b31115dd774062481e5b9b6739..3665976905e9a0e6c5d6f81e60f0cf8fec175c45 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 \r
 <JUCERPROJECT id="Z2Xzcp" name="UnitTestRunner" projectType="consoleapp" bundleIdentifier="com.roli.UnitTestRunner"\r
-              jucerVersion="5.3.0" defines="JUCE_UNIT_TESTS=1" displaySplashScreen="0"\r
+              jucerVersion="5.3.1" defines="JUCE_UNIT_TESTS=1" displaySplashScreen="0"\r
               reportAppUsage="0" companyName="ROLI Ltd." companyCopyright="ROLI Ltd.">\r
   <MAINGROUP id="GZdWCU" name="UnitTestRunner">\r
     <GROUP id="{22894462-E1A9-036F-ED94-B51A50C87552}" name="Source">\r
@@ -9,7 +9,7 @@
     </GROUP>\r
   </MAINGROUP>\r
   <EXPORTFORMATS>\r
-    <XCODE_MAC targetFolder="Builds/MacOSX" extraCompilerFlags="-Wall -Wshadow -Wstrict-aliasing -Wconversion -Wsign-compare -Woverloaded-virtual -Wextra-semi"\r
+    <XCODE_MAC targetFolder="Builds/MacOSX" extraCompilerFlags="-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -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 -Wno-ignored-qualifiers -Wunreachable-code"\r
                extraDefs="">\r
       <CONFIGURATIONS>\r
         <CONFIGURATION name="Debug" osxCompatibility="10.10 SDK" isDebug="1" targetName="UnitTestRunner"\r
index f5c1a2f0aff81fc68d4afe4324f9f55a7195cfac..92109b0740684ac934a840a191129945b640312a 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <ExcludedFromBuild>true</ExcludedFromBuild>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_BooleanPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ButtonPropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h"/>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyPanel.h"/>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_SliderPropertyComponent.h"/>\r
index 02dc419cc7d1ae217d83ad45c713fdbe894a9812..898a4b47899dad3c9f481148a3807098758227a6 100644 (file)
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_ALSA.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_Bela.cpp">\r
+      <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_linux_JackAudio.cpp">\r
       <Filter>JUCE Modules\juce_audio_devices\native</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LegacyAudioParameter.cpp">\r
+      <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3PluginFormat.cpp">\r
       <Filter>JUCE Modules\juce_audio_processors\format_types</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.cpp">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.cpp">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClCompile>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_ChoicePropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_MultiChoicePropertyComponent.h">\r
+      <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\..\..\..\modules\juce_gui_basics\properties\juce_PropertyComponent.h">\r
       <Filter>JUCE Modules\juce_gui_basics\properties</Filter>\r
     </ClInclude>\r
index a6c161e0d0666400772c115c239cf1847d8d039d..de3a1d428cde8e4642ac81c3dfab9bc2fac9f9d1 100644 (file)
  //#define JUCE_JACK 0\r
 #endif\r
 \r
+#ifndef    JUCE_BELA\r
+ //#define JUCE_BELA 0\r
+#endif\r
+\r
 #ifndef    JUCE_USE_ANDROID_OBOE\r
  //#define JUCE_USE_ANDROID_OBOE 0\r
 #endif\r
index dc0dd21afea6ba598b89e3930a5ac7ebb5ef90a3..55b3b27504eeaef748d4e6884ac844a65fb85383 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 \r
 <JUCERPROJECT id="IvabE4" name="WindowsDLL" projectType="library" juceLinkage="none"\r
-              bundleIdentifier="com.roli.jucedll" jucerVersion="5.3.0" defines="JUCE_DLL_BUILD=1"\r
+              bundleIdentifier="com.roli.jucedll" jucerVersion="5.3.1" defines="JUCE_DLL_BUILD=1"\r
               displaySplashScreen="0" reportAppUsage="0" companyName="ROLI Ltd."\r
               companyCopyright="ROLI Ltd.">\r
   <EXPORTFORMATS>\r
index a80747cde74119c6edbc4fc85fdf4e14415bfa9e..6bc6b3d0a0199bf2a1f441ff7d45bdefd95e7ada 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_analytics\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE analytics classes\r
   description:      Classes to collect analytics and send to destinations\r
   website:          http://www.juce.com/juce\r
index 8c3c78962705254c4680b174f21008ee31931268..f86e1255228c6671f63ef4497fe3db2b182a3da2 100644 (file)
@@ -31,7 +31,7 @@
 \r
   ID:               juce_audio_basics\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE audio and MIDI data classes\r
   description:      Classes for audio buffer manipulation, midi message handling, synthesis, etc.\r
   website:          http://www.juce.com/juce\r
index 5113c16f240605a5d260d671efcf829adacf5d38..0321e466748fe5e2a23063a6e4ecd61c19852b07 100644 (file)
@@ -35,7 +35,14 @@ MidiMessageSequence::MidiMessageSequence()
 MidiMessageSequence::MidiMessageSequence (const MidiMessageSequence& other)\r
 {\r
     list.addCopiesOf (other.list);\r
-    updateMatchedPairs();\r
+\r
+    for (int i = 0; i < list.size(); ++i)\r
+    {\r
+        auto noteOffIndex = other.getIndexOfMatchingKeyUp (i);\r
+\r
+        if (noteOffIndex >= 0)\r
+            list.getUnchecked(i)->noteOffObject = list.getUnchecked (noteOffIndex);\r
+    }\r
 }\r
 \r
 MidiMessageSequence& MidiMessageSequence::operator= (const MidiMessageSequence& other)\r
@@ -86,16 +93,25 @@ MidiMessageSequence::MidiEventHolder** MidiMessageSequence::end() const noexcept
 double MidiMessageSequence::getTimeOfMatchingKeyUp (int index) const noexcept\r
 {\r
     if (auto* meh = list[index])\r
-        if (meh->noteOffObject != nullptr)\r
-            return meh->noteOffObject->message.getTimeStamp();\r
+        if (auto* noteOff = meh->noteOffObject)\r
+            return noteOff->message.getTimeStamp();\r
 \r
-    return 0.0;\r
+    return 0;\r
 }\r
 \r
 int MidiMessageSequence::getIndexOfMatchingKeyUp (int index) const noexcept\r
 {\r
-    if (auto* meh = list [index])\r
-        return list.indexOf (meh->noteOffObject);\r
+    if (auto* meh = list[index])\r
+    {\r
+        if (auto* noteOff = meh->noteOffObject)\r
+        {\r
+            for (int i = index; i < list.size(); ++i)\r
+                if (list.getUnchecked(i) == noteOff)\r
+                    return i;\r
+\r
+            jassertfalse; // we've somehow got a pointer to a note-off object that isn't in the sequence\r
+        }\r
+    }\r
 \r
     return -1;\r
 }\r
@@ -108,8 +124,8 @@ int MidiMessageSequence::getIndexOf (const MidiEventHolder* event) const noexcep
 int MidiMessageSequence::getNextIndexAtTime (double timeStamp) const noexcept\r
 {\r
     auto numEvents = list.size();\r
-\r
     int i;\r
+\r
     for (i = 0; i < numEvents; ++i)\r
         if (list.getUnchecked(i)->message.getTimeStamp() >= timeStamp)\r
             break;\r
@@ -130,10 +146,10 @@ double MidiMessageSequence::getEndTime() const noexcept
 \r
 double MidiMessageSequence::getEventTime (const int index) const noexcept\r
 {\r
-    if (auto* meh = list [index])\r
+    if (auto* meh = list[index])\r
         return meh->message.getTimeStamp();\r
 \r
-    return 0.0;\r
+    return 0;\r
 }\r
 \r
 //==============================================================================\r
@@ -141,8 +157,8 @@ MidiMessageSequence::MidiEventHolder* MidiMessageSequence::addEvent (MidiEventHo
 {\r
     newEvent->message.addToTimeStamp (timeAdjustment);\r
     auto time = newEvent->message.getTimeStamp();\r
-\r
     int i;\r
+\r
     for (i = list.size(); --i >= 0;)\r
         if (list.getUnchecked(i)->message.getTimeStamp() <= time)\r
             break;\r
@@ -315,7 +331,7 @@ void MidiMessageSequence::createControllerUpdatesForTime (int channelNumber, dou
             }\r
             else if (mm.isController())\r
             {\r
-                const int controllerNumber = mm.getControllerNumber();\r
+                auto controllerNumber = mm.getControllerNumber();\r
                 jassert (isPositiveAndBelow (controllerNumber, 128));\r
 \r
                 if (! doneControllers[controllerNumber])\r
index 8fa387a63801930969bf9122ced4d73fbba5b188..fe79a371ed177e6cb2584b038d273efb39f8a5b6 100644 (file)
@@ -23,7 +23,7 @@
 namespace juce\r
 {\r
 \r
-#if JUCE_MAC || JUCE_IOS && ! DOXYGEN\r
+#if ! DOXYGEN && (JUCE_MAC || JUCE_IOS)\r
 \r
 struct CoreAudioLayouts\r
 {\r
index 732c058d101c12df897707eb823e8bcda347d851..4685e43509a11d73a79620d7fac779327643d0c6 100644 (file)
@@ -158,6 +158,7 @@ void AudioDeviceManager::createAudioDeviceTypes (OwnedArray<AudioIODeviceType>&
     addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_iOSAudio());\r
     addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ALSA());\r
     addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_JACK());\r
+    addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Bela());\r
     addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Oboe());\r
     addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_OpenSLES());\r
     addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Android());\r
index cb609d592fa72426bbd3d9ce4de8a95ab328a147..63f9e7fd5a19c49623b582893b58fa291e99691a 100644 (file)
@@ -70,6 +70,10 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA()
 AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK()            { return nullptr; }\r
 #endif\r
 \r
+#if ! (JUCE_LINUX && JUCE_BELA)\r
+AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Bela()            { return nullptr; }\r
+#endif\r
+\r
 #if ! JUCE_ANDROID\r
 AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android()         { return nullptr; }\r
 #endif\r
index a3d2d73ac12793805d0ef3fbdb834d050b54b8cb..f7b3236f63efead91553ae42a1886396cb12a07a 100644 (file)
@@ -165,6 +165,8 @@ public:
     static AudioIODeviceType* createAudioIODeviceType_OpenSLES();\r
     /** Creates an Oboe device type if it's available on this platform, or returns null. */\r
     static AudioIODeviceType* createAudioIODeviceType_Oboe();\r
+    /** Creates a Bela device type if it's available on this platform, or returns null. */\r
+    static AudioIODeviceType* createAudioIODeviceType_Bela();\r
 \r
 protected:\r
     explicit AudioIODeviceType (const String& typeName);\r
index 731a63ebeb93bfb027610e5b27da5f015eed69f5..67f36912dd956583194af802c45401ec769f9249 100644 (file)
   */\r
   #include <jack/jack.h>\r
  #endif\r
+\r
+ #if JUCE_BELA\r
+  /* Got an include error here? If so, you've either not got the bela headers\r
+     installed, or you've not got your paths set up correctly to find its header\r
+     files.\r
+  */\r
+  #include <Bela.h>\r
+ #endif\r
+\r
  #undef SIZEOF\r
 \r
 //==============================================================================\r
   #include "native/juce_linux_JackAudio.cpp"\r
  #endif\r
 \r
+ #if JUCE_BELA\r
+  #include "native/juce_linux_Bela.cpp"\r
+ #endif\r
+\r
 //==============================================================================\r
 #elif JUCE_ANDROID\r
  #include "native/juce_android_Audio.cpp"\r
index bf18e02efad4f70770f322a562ec24b32e063afd..611f653978ac379279a9929c878197c20c4fdcf3 100644 (file)
@@ -31,7 +31,7 @@
 \r
   ID:               juce_audio_devices\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE audio and MIDI I/O device classes\r
   description:      Classes to play and record from audio and MIDI I/O devices\r
   website:          http://www.juce.com/juce\r
  #define JUCE_JACK 0\r
 #endif\r
 \r
+/** Config: JUCE_BELA\r
+    Enables Bela audio devices on Bela boards.\r
+*/\r
+#ifndef JUCE_BELA\r
+ #define JUCE_BELA 0\r
+#endif\r
+\r
 /** Config: JUCE_USE_ANDROID_OBOE\r
     ***\r
     DEVELOPER PREVIEW - Oboe is currently in developer preview and\r
index 34c31651a71d4838b101045a43f226aec9f550f5..3b9a11a10de182bc83287c8f11fc7776b18e5fb8 100644 (file)
@@ -978,9 +978,8 @@ private:
 class ALSAAudioIODeviceType  : public AudioIODeviceType\r
 {\r
 public:\r
-    ALSAAudioIODeviceType (bool onlySoundcards, const String &deviceTypeName)\r
+    ALSAAudioIODeviceType (bool onlySoundcards, const StringdeviceTypeName)\r
         : AudioIODeviceType (deviceTypeName),\r
-          hasScanned (false),\r
           listOnlySoundcards (onlySoundcards)\r
     {\r
        #if ! JUCE_ALSA_LOGGING\r
@@ -1041,7 +1040,7 @@ public:
     {\r
         jassert (hasScanned); // need to call scanForDevices() before doing this\r
 \r
-        if (ALSAAudioIODevice* d = dynamic_cast<ALSAAudioIODevice*> (device))\r
+        if (auto* d = dynamic_cast<ALSAAudioIODevice*> (device))\r
             return asInput ? inputIds.indexOf (d->inputId)\r
                            : outputIds.indexOf (d->outputId);\r
 \r
@@ -1070,9 +1069,9 @@ public:
 private:\r
     //==============================================================================\r
     StringArray inputNames, outputNames, inputIds, outputIds;\r
-    bool hasScanned, listOnlySoundcards;\r
+    bool hasScanned = false, listOnlySoundcards;\r
 \r
-    bool testDevice (const String &id, const String &outputName, const String &inputName)\r
+    bool testDevice (const String& id, const String& outputName, const String& inputName)\r
     {\r
         unsigned int minChansOut = 0, maxChansOut = 0;\r
         unsigned int minChansIn = 0, maxChansIn = 0;\r
diff --git a/modules/juce_audio_devices/native/juce_linux_Bela.cpp b/modules/juce_audio_devices/native/juce_linux_Bela.cpp
new file mode 100644 (file)
index 0000000..cfe8dc8
--- /dev/null
@@ -0,0 +1,373 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   The code included in this file is provided under the terms of the ISC license\r
+   http://www.isc.org/downloads/software-support-policy/isc-license. Permission\r
+   To use, copy, modify, and/or distribute this software for any purpose with or\r
+   without fee is hereby granted provided that the above copyright notice and\r
+   this permission notice appear in all copies.\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+namespace juce\r
+{\r
+\r
+//==============================================================================\r
+class BelaAudioIODevice   : public AudioIODevice\r
+{\r
+public:\r
+    BelaAudioIODevice()  : AudioIODevice (BelaAudioIODevice::belaTypeName,\r
+                                          BelaAudioIODevice::belaTypeName)\r
+    {\r
+        Bela_defaultSettings (&defaultSettings);\r
+    }\r
+\r
+    ~BelaAudioIODevice() {}\r
+\r
+    //==============================================================================\r
+    StringArray getOutputChannelNames() override           { return { "Out #1", "Out #2" }; }\r
+    StringArray getInputChannelNames() override            { return { "In #1",  "In #2" }; }\r
+    Array<double> getAvailableSampleRates() override       { return { 44100.0 }; }\r
+    Array<int> getAvailableBufferSizes() override          { /* TODO: */ return { getDefaultBufferSize() }; }\r
+    int getDefaultBufferSize() override                    { return defaultSettings.periodSize; }\r
+\r
+    //==============================================================================\r
+    String open (const BigInteger& inputChannels,\r
+                 const BigInteger& outputChannels,\r
+                 double sampleRate,\r
+                 int bufferSizeSamples) override\r
+    {\r
+        if (sampleRate != 44100.0 && sampleRate != 0.0)\r
+        {\r
+            lastError = "Bela audio outputs only support 44.1 kHz sample rate";\r
+            return lastError;\r
+        }\r
+\r
+        settings = defaultSettings;\r
+\r
+        auto numIns = getNumContiguousSetBits (inputChannels);\r
+        auto numOuts = getNumContiguousSetBits (outputChannels);\r
+\r
+        settings.useAnalog            = 0;\r
+        settings.useDigital           = 0;\r
+        settings.numAudioInChannels   = numIns;\r
+        settings.numAudioOutChannels  = numOuts;\r
+        settings.detectUnderruns      = 1;\r
+        settings.setup                = setupCallback;\r
+        settings.render               = renderCallback;\r
+        settings.cleanup              = cleanupCallback;\r
+        settings.interleave           = 1;\r
+\r
+        if (bufferSizeSamples > 0)\r
+            settings.periodSize = bufferSizeSamples;\r
+\r
+        isBelaOpen = false;\r
+        isRunning  = false;\r
+        callback   = nullptr;\r
+        underruns  = 0;\r
+\r
+        if (Bela_initAudio (&settings, this) != 0 || ! isBelaOpen)\r
+        {\r
+            lastError = "Bela_initAutio failed";\r
+            return lastError;\r
+        }\r
+\r
+        actualNumberOfInputs  = jmin (numIns, actualNumberOfInputs);\r
+        actualNumberOfOutputs = jmin (numOuts, actualNumberOfOutputs);\r
+\r
+        audioInBuffer.setSize (actualNumberOfInputs, actualBufferSize);\r
+        channelInBuffer.calloc (actualNumberOfInputs);\r
+\r
+        audioOutBuffer.setSize (actualNumberOfOutputs, actualBufferSize);\r
+        channelOutBuffer.calloc (actualNumberOfOutputs);\r
+\r
+        return {};\r
+    }\r
+\r
+    void close() override\r
+    {\r
+        stop();\r
+\r
+        if (isBelaOpen)\r
+        {\r
+            Bela_cleanupAudio();\r
+\r
+            isBelaOpen = false;\r
+            callback = nullptr;\r
+            underruns = 0;\r
+\r
+            actualBufferSize = 0;\r
+            actualNumberOfInputs = 0;\r
+            actualNumberOfOutputs = 0;\r
+\r
+            audioInBuffer.setSize (0, 0);\r
+            channelInBuffer.free();\r
+\r
+            audioOutBuffer.setSize (0, 0);\r
+            channelOutBuffer.free();\r
+        }\r
+    }\r
+\r
+    bool isOpen() override   { return isBelaOpen; }\r
+\r
+    void start (AudioIODeviceCallback* newCallback) override\r
+    {\r
+        if (! isBelaOpen)\r
+            return;\r
+\r
+        if (isRunning)\r
+        {\r
+            if (newCallback != callback)\r
+            {\r
+                if (newCallback != nullptr)\r
+                    newCallback->audioDeviceAboutToStart (this);\r
+\r
+                {\r
+                    ScopedLock lock (callbackLock);\r
+                    std::swap (callback, newCallback);\r
+                }\r
+\r
+                if (newCallback != nullptr)\r
+                    newCallback->audioDeviceStopped();\r
+            }\r
+        }\r
+        else\r
+        {\r
+            audioInBuffer.clear();\r
+            audioOutBuffer.clear();\r
+\r
+            callback = newCallback;\r
+            isRunning = (Bela_startAudio() == 0);\r
+\r
+            if (callback != nullptr)\r
+            {\r
+                if (isRunning)\r
+                {\r
+                    callback->audioDeviceAboutToStart (this);\r
+                }\r
+                else\r
+                {\r
+                    lastError = "Bela_StartAudio failed";\r
+                    callback->audioDeviceError (lastError);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    void stop() override\r
+    {\r
+        AudioIODeviceCallback* oldCallback = nullptr;\r
+\r
+        if (callback != nullptr)\r
+        {\r
+            ScopedLock lock (callbackLock);\r
+            std::swap (callback, oldCallback);\r
+        }\r
+\r
+        isRunning = false;\r
+        Bela_stopAudio();\r
+\r
+        if (oldCallback != nullptr)\r
+            oldCallback->audioDeviceStopped();\r
+    }\r
+\r
+    bool isPlaying() override         { return isRunning; }\r
+    String getLastError() override    { return lastError; }\r
+\r
+    //==============================================================================\r
+    int getCurrentBufferSizeSamples() override            { return actualBufferSize; }\r
+    double getCurrentSampleRate() override                { return 44100.0; }\r
+    int getCurrentBitDepth() override                     { return 24; }\r
+    BigInteger getActiveOutputChannels() const override   { BigInteger b; b.setRange (0, actualNumberOfOutputs, true); return b; }\r
+    BigInteger getActiveInputChannels() const override    { BigInteger b; b.setRange (0, actualNumberOfInputs, true);  return b; }\r
+    int getOutputLatencyInSamples() override              { /* TODO */ return 0; }\r
+    int getInputLatencyInSamples() override               { /* TODO */ return 0; }\r
+    int getXRunCount() const noexcept                     { return underruns; }\r
+\r
+    //==============================================================================\r
+    static const char* const belaTypeName;\r
+\r
+private:\r
+    //==============================================================================\r
+    bool setup (BelaContext& context)\r
+    {\r
+        actualBufferSize      = context.audioFrames;\r
+        actualNumberOfInputs  = context.audioInChannels;\r
+        actualNumberOfOutputs = context.audioOutChannels;\r
+        isBelaOpen = true;\r
+        firstCallback = true;\r
+\r
+        ScopedLock lock (callbackLock);\r
+\r
+        if (callback != nullptr)\r
+            callback->audioDeviceAboutToStart (this);\r
+\r
+        return true;\r
+    }\r
+\r
+    void render (BelaContext& context)\r
+    {\r
+        // check for xruns\r
+        calculateXruns (context.audioFramesElapsed, context.audioFrames);\r
+\r
+        ScopedLock lock (callbackLock);\r
+\r
+        if (callback != nullptr)\r
+        {\r
+            jassert (context.audioFrames <= actualBufferSize);\r
+            auto numSamples = jmin (context.audioFrames, actualBufferSize);\r
+            auto interleaved = ((context.flags & BELA_FLAG_INTERLEAVED) != 0);\r
+            auto numIns  = jmin (actualNumberOfInputs,  (int) context.audioInChannels);\r
+            auto numOuts = jmin (actualNumberOfOutputs, (int) context.audioOutChannels);\r
+\r
+            int ch;\r
+\r
+            if (interleaved && context.audioInChannels > 1)\r
+            {\r
+                for (ch = 0; ch < numIns; ++ch)\r
+                {\r
+                    using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst>;\r
+                    using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved,    AudioData::Const>;\r
+\r
+                    channelInBuffer[ch] = audioInBuffer.getWritePointer (ch);\r
+                    DstSampleType dstData (audioInBuffer.getWritePointer (ch));\r
+                    SrcSampleType srcData (context.audioIn + ch, context.audioInChannels);\r
+                    dstData.convertSamples (srcData, numSamples);\r
+                }\r
+            }\r
+            else\r
+            {\r
+                for (ch = 0; ch < numIns; ++ch)\r
+                    channelInBuffer[ch] = context.audioIn + (ch * numSamples);\r
+            }\r
+\r
+            for (; ch < actualNumberOfInputs; ++ch)\r
+            {\r
+                channelInBuffer[ch] = audioInBuffer.getWritePointer(ch);\r
+                zeromem (audioInBuffer.getWritePointer (ch), sizeof (float) * numSamples);\r
+            }\r
+\r
+            for (int i = 0; i < actualNumberOfOutputs; ++i)\r
+                channelOutBuffer[i] = ((interleaved && context.audioOutChannels > 1) || i >= context.audioOutChannels ? audioOutBuffer.getWritePointer (i)\r
+                                                                                                                      : context.audioOut + (i * numSamples));\r
+\r
+            callback->audioDeviceIOCallback (channelInBuffer.getData(), actualNumberOfInputs,\r
+                                             channelOutBuffer.getData(), actualNumberOfOutputs,\r
+                                             numSamples);\r
+\r
+            if (interleaved && context.audioOutChannels > 1)\r
+            {\r
+                for (int i = 0; i < numOuts; ++i)\r
+                {\r
+                    using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved,    AudioData::NonConst>;\r
+                    using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const>;\r
+\r
+                    SrcSampleType srcData (channelOutBuffer[i]);\r
+                    DstSampleType dstData (context.audioOut + i, context.audioOutChannels);\r
+\r
+                    dstData.convertSamples (srcData, numSamples);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    void cleanup (BelaContext&)\r
+    {\r
+        ScopedLock lock (callbackLock);\r
+\r
+        if (callback != nullptr)\r
+            callback->audioDeviceStopped();\r
+    }\r
+\r
+\r
+    //==============================================================================\r
+    uint64_t expectedElapsedAudioSamples = 0;\r
+    int underruns = 0;\r
+    bool firstCallback = false;\r
+\r
+    void calculateXruns (uint64_t audioFramesElapsed, uint32_t numSamples)\r
+    {\r
+        if (audioFramesElapsed > expectedElapsedAudioSamples && ! firstCallback)\r
+            ++underruns;\r
+\r
+        firstCallback = false;\r
+        expectedElapsedAudioSamples = audioFramesElapsed + numSamples;\r
+    }\r
+\r
+    //==============================================================================\r
+    static int getNumContiguousSetBits (const BigInteger& value) noexcept\r
+    {\r
+        int bit = 0;\r
+\r
+        while (value[bit])\r
+            ++bit;\r
+\r
+        return bit;\r
+    }\r
+\r
+    //==============================================================================\r
+    static bool setupCallback   (BelaContext* context, void* userData) noexcept    { return static_cast<BelaAudioIODevice*> (userData)->setup (*context); }\r
+    static void renderCallback  (BelaContext* context, void* userData) noexcept    { static_cast<BelaAudioIODevice*> (userData)->render (*context); }\r
+    static void cleanupCallback (BelaContext* context, void* userData) noexcept    { static_cast<BelaAudioIODevice*> (userData)->cleanup (*context); }\r
+\r
+    //==============================================================================\r
+    BelaInitSettings defaultSettings, settings;\r
+    bool isBelaOpen = false, isRunning = false;\r
+\r
+    CriticalSection callbackLock;\r
+    AudioIODeviceCallback* callback = nullptr;\r
+\r
+    String lastError;\r
+    uint32_t actualBufferSize = 0;\r
+    int actualNumberOfInputs = 0, actualNumberOfOutputs = 0;\r
+\r
+    AudioBuffer<float> audioInBuffer, audioOutBuffer;\r
+    HeapBlock<const float*> channelInBuffer;\r
+    HeapBlock<float*> channelOutBuffer;\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BelaAudioIODevice)\r
+};\r
+\r
+const char* const BelaAudioIODevice::belaTypeName = "Bela Analog";\r
+\r
+//==============================================================================\r
+struct BelaAudioIODeviceType  : public AudioIODeviceType\r
+{\r
+    BelaAudioIODeviceType() : AudioIODeviceType ("Bela") {}\r
+\r
+    // TODO: support analog outputs\r
+    StringArray getDeviceNames (bool) const override                       { return StringArray (BelaAudioIODevice::belaTypeName); }\r
+    void scanForDevices() override                                         {}\r
+    int getDefaultDeviceIndex (bool) const override                        { return 0; }\r
+    int getIndexOfDevice (AudioIODevice* device, bool) const override      { return device != nullptr ? 0 : -1; }\r
+    bool hasSeparateInputsAndOutputs() const override                      { return false; }\r
+\r
+    AudioIODevice* createDevice (const String& outputName, const String& inputName) override\r
+    {\r
+        if (outputName == BelaAudioIODevice::belaTypeName || inputName == BelaAudioIODevice::belaTypeName)\r
+            return new BelaAudioIODevice();\r
+\r
+        return nullptr;\r
+    }\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BelaAudioIODeviceType)\r
+};\r
+\r
+//==============================================================================\r
+AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Bela()\r
+{\r
+    return new BelaAudioIODeviceType();\r
+}\r
+\r
+} // namespace juce\r
index e61cac416ef7d50ff13118baffa0deb54826ea43..6a7d2bb8c20706a487a5b48f87be76801ddee054 100644 (file)
@@ -321,13 +321,29 @@ private:
     //==============================================================================\r
     struct WindowsOutputWrapper  : public OutputWrapper\r
     {\r
-        struct MidiOutHandle\r
+        struct MidiOutHandle    : public ReferenceCountedObject\r
         {\r
-            int refCount;\r
+            using Ptr = ReferenceCountedObjectPtr<MidiOutHandle>;\r
+\r
+            MidiOutHandle (WindowsMidiService& parent, UINT id, HMIDIOUT h)\r
+                : owner (parent), deviceId (id), handle (h)\r
+            {\r
+                owner.activeOutputHandles.add (this);\r
+            }\r
+\r
+            ~MidiOutHandle()\r
+            {\r
+                if (handle != nullptr)\r
+                    midiOutClose (handle);\r
+\r
+                owner.activeOutputHandles.removeFirstMatchingValue (this);\r
+            }\r
+\r
+            WindowsMidiService& owner;\r
             UINT deviceId;\r
             HMIDIOUT handle;\r
 \r
-            JUCE_LEAK_DETECTOR (MidiOutHandle)\r
+            JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiOutHandle)\r
         };\r
 \r
         WindowsOutputWrapper (WindowsMidiService& p, int index) : parent (p)\r
@@ -356,7 +372,6 @@ private:
 \r
                 if (activeHandle->deviceId == deviceId)\r
                 {\r
-                    activeHandle->refCount++;\r
                     han = activeHandle;\r
                     return;\r
                 }\r
@@ -369,11 +384,7 @@ private:
 \r
                 if (res == MMSYSERR_NOERROR)\r
                 {\r
-                    han = new MidiOutHandle();\r
-                    han->deviceId = deviceId;\r
-                    han->refCount = 1;\r
-                    han->handle = h;\r
-                    parent.activeOutputHandles.add (han);\r
+                    han = new MidiOutHandle (parent, deviceId, h);\r
                     return;\r
                 }\r
 \r
@@ -386,15 +397,6 @@ private:
             throw std::runtime_error ("Failed to create Windows output device wrapper");\r
         }\r
 \r
-        ~WindowsOutputWrapper()\r
-        {\r
-            if (parent.activeOutputHandles.contains (han.get()) && --(han->refCount) == 0)\r
-            {\r
-                midiOutClose (han->handle);\r
-                parent.activeOutputHandles.removeFirstMatchingValue (han.get());\r
-            }\r
-        }\r
-\r
         void sendMessageNow (const MidiMessage& message) override\r
         {\r
             if (message.getRawDataSize() > 3 || message.isSysEx())\r
@@ -489,7 +491,7 @@ private:
         WindowsMidiService& parent;\r
         String deviceName;\r
 \r
-        ScopedPointer<MidiOutHandle> han;\r
+        MidiOutHandle::Ptr han;\r
 \r
         JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsOutputWrapper)\r
     };\r
index 0f0c6f21956483944b1ed423b46a9d43a482283c..1954b8b89fc59fe43c808ad4a675e63be895bcca 100644 (file)
@@ -157,8 +157,8 @@ const char* const WavAudioFormat::tracktionLoopInfo    = "tracktion loop info";
 //==============================================================================\r
 namespace WavFileHelpers\r
 {\r
-    inline int chunkName (const char* const name) noexcept   { return (int) ByteOrder::littleEndianInt (name[0], name[1], name[2], name[3]); }\r
-    inline size_t roundUpSize (size_t sz) noexcept           { return (sz + 3) & ~3u; }\r
+    JUCE_CONSTEXPR inline int chunkName (const char* name) noexcept         { return (int) ByteOrder::littleEndianInt (name); }\r
+    JUCE_CONSTEXPR inline size_t roundUpSize (size_t sz) noexcept           { return (sz + 3) & ~3u; }\r
 \r
     #if JUCE_MSVC\r
      #pragma pack (push, 1)\r
index 23f802dc2563f141e2db98426cef2bb6855ff02e..c8d816d3f08e4d6cf2e31efdfffc5a8dfe6f892d 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_audio_formats\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE audio file format codecs\r
   description:      Classes for reading and writing various audio file formats.\r
   website:          http://www.juce.com/juce\r
index fae56368dc926dbfe81108ebe242a0a97b5b26e3..d698d0e6502f003c8d2aee7476538bbae1162ea1 100644 (file)
@@ -34,6 +34,8 @@
 #include "../utility/juce_WindowsHooks.h"\r
 #include "../utility/juce_FakeMouseMoveGenerator.h"\r
 \r
+#include "../../juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp"\r
+\r
 #ifdef __clang__\r
  #pragma clang diagnostic push\r
  #pragma clang diagnostic ignored "-Wnon-virtual-dtor"\r
@@ -71,6 +73,13 @@ static_assert (AAX_SDK_CURRENT_REVISION >= AAX_SDK_2p3p0_REVISION, "JUCE require
 #include <AAX_IFeatureInfo.h>\r
 #include <AAX_UIDs.h>\r
 \r
+#ifdef AAX_SDK_2p3p1_REVISION\r
+ #if AAX_SDK_CURRENT_REVISION >= AAX_SDK_2p3p1_REVISION\r
+  #include <AAX_Exception.h>\r
+  #include <AAX_Assert.h>\r
+ #endif\r
+#endif\r
+\r
 #ifdef _MSC_VER\r
  #pragma warning (pop)\r
 #endif\r
@@ -131,11 +140,6 @@ namespace AAXClasses
         jassert (result == AAX_SUCCESS); ignoreUnused (result);\r
     }\r
 \r
-    static bool isBypassParam (AAX_CParamID paramID) noexcept\r
-    {\r
-        return AAX::IsParameterIDEqual (paramID, cDefaultMasterBypassID) != 0;\r
-    }\r
-\r
     // maps a channel index of an AAX format to an index of a juce format\r
     struct AAXChannelStreamOrder\r
     {\r
@@ -481,10 +485,12 @@ namespace AAXClasses
         {\r
             if (component != nullptr && component->pluginEditor != nullptr)\r
             {\r
-                if (! isBypassParam (paramID))\r
+                auto index = getParamIndexFromID (paramID);\r
+\r
+                if (index >= 0)\r
                 {\r
                     AudioProcessorEditor::ParameterControlHighlightInfo info;\r
-                    info.parameterIndex  = getParamIndexFromID (paramID);\r
+                    info.parameterIndex  = index;\r
                     info.isHighlighted   = (isHighlighted != 0);\r
                     info.suggestedColour = getColourFromHighlightEnum (colour);\r
 \r
@@ -531,7 +537,8 @@ namespace AAXClasses
 \r
                 if (pluginEditor != nullptr)\r
                 {\r
-                    setBounds (pluginEditor->getLocalBounds());\r
+                    lastValidSize = pluginEditor->getLocalBounds();\r
+                    setBounds (lastValidSize);\r
                     pluginEditor->addMouseListener (this, true);\r
                 }\r
 \r
@@ -580,10 +587,19 @@ namespace AAXClasses
                 {\r
                     auto w = pluginEditor->getWidth();\r
                     auto h = pluginEditor->getHeight();\r
-                    setSize (w, h);\r
 \r
                     AAX_Point newSize ((float) h, (float) w);\r
-                    owner.GetViewContainer()->SetViewSize (newSize);\r
+\r
+                    if (owner.GetViewContainer()->SetViewSize (newSize) == AAX_SUCCESS)\r
+                    {\r
+                        setSize (w, h);\r
+                        lastValidSize = getBounds();\r
+                    }\r
+                    else\r
+                    {\r
+                        auto validSize = pluginEditor->getBounds().withSize (lastValidSize.getWidth(), lastValidSize.getHeight());\r
+                        pluginEditor->setBoundsConstrained (validSize);\r
+                    }\r
                 }\r
             }\r
 \r
@@ -594,6 +610,7 @@ namespace AAXClasses
             WindowsHooks hooks;\r
            #endif\r
             FakeMouseMoveGenerator fakeMouseGenerator;\r
+            juce::Rectangle<int> lastValidSize;\r
 \r
             JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentWrapperComponent)\r
         };\r
@@ -635,6 +652,7 @@ namespace AAXClasses
         AAX_Result Uninitialize() override\r
         {\r
             cancelPendingUpdate();\r
+            juceParameters.clear();\r
 \r
             if (isPrepared && pluginInstance != nullptr)\r
             {\r
@@ -657,7 +675,6 @@ namespace AAXClasses
             if (err != AAX_SUCCESS)\r
                 return err;\r
 \r
-            addBypassParameter();\r
             addAudioProcessorParameters();\r
 \r
             return AAX_SUCCESS;\r
@@ -724,11 +741,11 @@ namespace AAXClasses
             // * The preset is loaded in PT 10 using the AAX version.\r
             // * The session is then saved, and closed.\r
             // * The saved session is loaded, but acting as if the preset was never loaded.\r
-            auto numParameters = pluginInstance->getNumParameters();\r
+            auto numParameters = juceParameters.getNumParameters();\r
 \r
             for (int i = 0; i < numParameters; ++i)\r
                 if (auto paramID = getAAXParamIDFromJuceIndex(i))\r
-                    SetParameterNormalizedValue (paramID, (double) pluginInstance->getParameter(i));\r
+                    SetParameterNormalizedValue (paramID, juceParameters.getParamForIndex (i)->getValue());\r
 \r
             return AAX_SUCCESS;\r
         }\r
@@ -782,46 +799,39 @@ namespace AAXClasses
             return AAX_SUCCESS;\r
         }\r
 \r
-        void setAudioProcessorParameter (int index, float value)\r
+        void setAudioProcessorParameter (AAX_CParamID paramID, double value)\r
         {\r
-            if (auto* param = pluginInstance->getParameters()[index])\r
+            if (auto* param = getParameterFromID (paramID))\r
             {\r
-                if (value != param->getValue())\r
+                auto newValue = static_cast<float> (value);\r
+\r
+                if (newValue != param->getValue())\r
                 {\r
-                    param->setValue (value);\r
+                    param->setValue (newValue);\r
 \r
                     inParameterChangedCallback = true;\r
-                    param->sendValueChangedMessageToListeners (value);\r
+                    param->sendValueChangedMessageToListeners (newValue);\r
                 }\r
             }\r
-            else\r
-            {\r
-                pluginInstance->setParameter (index, value);\r
-            }\r
         }\r
 \r
         AAX_Result UpdateParameterNormalizedValue (AAX_CParamID paramID, double value, AAX_EUpdateSource source) override\r
         {\r
             auto result = AAX_CEffectParameters::UpdateParameterNormalizedValue (paramID, value, source);\r
-\r
-            if (! isBypassParam (paramID))\r
-                setAudioProcessorParameter (getParamIndexFromID (paramID), (float) value);\r
+            setAudioProcessorParameter (paramID, value);\r
 \r
             return result;\r
         }\r
 \r
         AAX_Result GetParameterValueFromString (AAX_CParamID paramID, double* result, const AAX_IString& text) const override\r
         {\r
-            if (isBypassParam (paramID))\r
+            if (auto* param = getParameterFromID (paramID))\r
             {\r
-                *result = (text.Get()[0] == 'B') ? 1.0 : 0.0;\r
-                return AAX_SUCCESS;\r
-            }\r
-\r
-            if (AudioProcessorParameter* param = pluginInstance->getParameters() [getParamIndexFromID (paramID)])\r
-            {\r
-                *result = param->getValueForText (text.Get());\r
-                return AAX_SUCCESS;\r
+                if (! LegacyAudioParameter::isLegacy (param))\r
+                {\r
+                    *result = param->getValueForText (text.Get());\r
+                    return AAX_SUCCESS;\r
+                }\r
             }\r
 \r
             return AAX_CEffectParameters::GetParameterValueFromString (paramID, result, text);\r
@@ -829,104 +839,79 @@ namespace AAXClasses
 \r
         AAX_Result GetParameterStringFromValue (AAX_CParamID paramID, double value, AAX_IString* result, int32_t maxLen) const override\r
         {\r
-            if (isBypassParam (paramID))\r
-            {\r
-                result->Set (value == 0 ? "Off" : (maxLen >= 8 ? "Bypassed" : "Byp"));\r
-            }\r
-            else\r
-            {\r
-                auto paramIndex = getParamIndexFromID (paramID);\r
-                juce::String text;\r
-\r
-                if (auto* param = pluginInstance->getParameters() [paramIndex])\r
-                    text = param->getText ((float) value, maxLen);\r
-                else\r
-                    text = pluginInstance->getParameterText (paramIndex, maxLen);\r
-\r
-                result->Set (text.toRawUTF8());\r
-            }\r
+            if (auto* param = getParameterFromID (paramID))\r
+                result->Set (param->getText ((float) value, maxLen).toRawUTF8());\r
 \r
             return AAX_SUCCESS;\r
         }\r
 \r
         AAX_Result GetParameterNumberofSteps (AAX_CParamID paramID, int32_t* result) const\r
         {\r
-            if (isBypassParam (paramID))\r
-                *result = 2;\r
-            else\r
-                *result = pluginInstance->getParameterNumSteps (getParamIndexFromID (paramID));\r
+            if (auto* param = getParameterFromID (paramID))\r
+                *result = param->getNumSteps();\r
 \r
             return AAX_SUCCESS;\r
         }\r
 \r
         AAX_Result GetParameterNormalizedValue (AAX_CParamID paramID, double* result) const override\r
         {\r
-            if (isBypassParam (paramID))\r
-                return AAX_CEffectParameters::GetParameterNormalizedValue (paramID, result);\r
+            if (auto* param = getParameterFromID (paramID))\r
+                *result = (double) param->getValue();\r
+            else\r
+                *result = 0.0;\r
 \r
-            *result = pluginInstance->getParameter (getParamIndexFromID (paramID));\r
             return AAX_SUCCESS;\r
         }\r
 \r
         AAX_Result SetParameterNormalizedValue (AAX_CParamID paramID, double newValue) override\r
         {\r
-            if (isBypassParam (paramID))\r
-                return AAX_CEffectParameters::SetParameterNormalizedValue (paramID, newValue);\r
-\r
             if (auto* p = mParameterManager.GetParameterByID (paramID))\r
                 p->SetValueWithFloat ((float) newValue);\r
 \r
-            setAudioProcessorParameter (getParamIndexFromID (paramID), (float) newValue);\r
+            setAudioProcessorParameter (paramID, (float) newValue);\r
 \r
             return AAX_SUCCESS;\r
         }\r
 \r
         AAX_Result SetParameterNormalizedRelative (AAX_CParamID paramID, double newDeltaValue) override\r
         {\r
-            if (isBypassParam (paramID))\r
-                return AAX_CEffectParameters::SetParameterNormalizedRelative (paramID, newDeltaValue);\r
-\r
-            auto paramIndex = getParamIndexFromID (paramID);\r
-            auto newValue = pluginInstance->getParameter (paramIndex) + (float) newDeltaValue;\r
+            if (auto* param = getParameterFromID (paramID))\r
+            {\r
+                auto newValue = param->getValue() + (float) newDeltaValue;\r
 \r
-            setAudioProcessorParameter (paramIndex, jlimit (0.0f, 1.0f, newValue));\r
+                setAudioProcessorParameter (paramID, jlimit (0.0f, 1.0f, newValue));\r
 \r
-            if (auto* p = mParameterManager.GetParameterByID (paramID))\r
-                p->SetValueWithFloat (newValue);\r
+                if (auto* p = mParameterManager.GetParameterByID (paramID))\r
+                    p->SetValueWithFloat (newValue);\r
+            }\r
 \r
             return AAX_SUCCESS;\r
         }\r
 \r
         AAX_Result GetParameterNameOfLength (AAX_CParamID paramID, AAX_IString* result, int32_t maxLen) const override\r
         {\r
-            if (isBypassParam (paramID))\r
-                result->Set (maxLen >= 13 ? "Master Bypass"\r
-                                          : (maxLen >= 8 ? "Mast Byp"\r
-                                                         : (maxLen >= 6 ? "MstByp" : "MByp")));\r
-            else\r
-                result->Set (pluginInstance->getParameterName (getParamIndexFromID (paramID), maxLen).toRawUTF8());\r
+            if (auto* param = getParameterFromID (paramID))\r
+                result->Set (param->getName (maxLen).toRawUTF8());\r
 \r
             return AAX_SUCCESS;\r
         }\r
 \r
         AAX_Result GetParameterName (AAX_CParamID paramID, AAX_IString* result) const override\r
         {\r
-            if (isBypassParam (paramID))\r
-                result->Set ("Master Bypass");\r
-            else\r
-                result->Set (pluginInstance->getParameterName (getParamIndexFromID (paramID), 31).toRawUTF8());\r
+            if (auto* param = getParameterFromID (paramID))\r
+                result->Set (param->getName (31).toRawUTF8());\r
 \r
             return AAX_SUCCESS;\r
         }\r
 \r
         AAX_Result GetParameterDefaultNormalizedValue (AAX_CParamID paramID, double* result) const override\r
         {\r
-            if (! isBypassParam (paramID))\r
-            {\r
-                *result = (double) pluginInstance->getParameterDefaultValue (getParamIndexFromID (paramID));\r
+            if (auto* param = getParameterFromID (paramID))\r
+                *result = (double) param->getDefaultValue();\r
+            else\r
+                *result = 0.0;\r
 \r
-                jassert (*result >= 0 && *result <= 1.0f);\r
-            }\r
+            jassert (*result >= 0 && *result <= 1.0f);\r
 \r
             return AAX_SUCCESS;\r
         }\r
@@ -1014,13 +999,13 @@ namespace AAXClasses
         {\r
             ++mNumPlugInChanges;\r
 \r
-            auto numParameters = pluginInstance->getNumParameters();\r
+            auto numParameters = juceParameters.getNumParameters();\r
 \r
             for (int i = 0; i < numParameters; ++i)\r
             {\r
                 if (auto* p = mParameterManager.GetParameterByID (getAAXParamIDFromJuceIndex (i)))\r
                 {\r
-                    auto newName = processor->getParameterName (i, 31);\r
+                    auto newName = juceParameters.getParamForIndex (i)->getName (31);\r
 \r
                     if (p->Name() != newName.toRawUTF8())\r
                         p->SetName (AAX_CString (newName.toRawUTF8()));\r
@@ -1158,7 +1143,7 @@ namespace AAXClasses
 \r
                 if (meterBuffers != nullptr)\r
                     for (int i = 0; i < numMeters; ++i)\r
-                        meterBuffers[i] = pluginInstance->getParameter (aaxMeters[i]);\r
+                        meterBuffers[i] = aaxMeters[i]->getValue();\r
             }\r
         }\r
 \r
@@ -1405,76 +1390,102 @@ namespace AAXClasses
            #endif\r
         }\r
 \r
-        void addBypassParameter()\r
+        bool isBypassPartOfRegularParemeters() const\r
         {\r
-            auto* masterBypass = new AAX_CParameter<bool> (cDefaultMasterBypassID,\r
-                                                           AAX_CString ("Master Bypass"),\r
-                                                           false,\r
-                                                           AAX_CBinaryTaperDelegate<bool>(),\r
-                                                           AAX_CBinaryDisplayDelegate<bool> ("bypass", "on"),\r
-                                                           true);\r
-            masterBypass->SetNumberOfSteps (2);\r
-            masterBypass->SetType (AAX_eParameterType_Discrete);\r
-            mParameterManager.AddParameter (masterBypass);\r
-            mPacketDispatcher.RegisterPacket (cDefaultMasterBypassID, JUCEAlgorithmIDs::bypass);\r
+            auto& audioProcessor = getPluginInstance();\r
+\r
+            int n = juceParameters.getNumParameters();\r
+\r
+            if (auto* bypassParam = audioProcessor.getBypassParameter())\r
+                for (int i = 0; i < n; ++i)\r
+                    if (juceParameters.getParamForIndex (i) == bypassParam)\r
+                        return true;\r
+\r
+            return false;\r
         }\r
 \r
         void addAudioProcessorParameters()\r
         {\r
             auto& audioProcessor = getPluginInstance();\r
-            auto numParameters = audioProcessor.getNumParameters();\r
 \r
            #if JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
-            const bool usingManagedParameters = false;\r
+            const bool forceLegacyParamIDs = true;\r
            #else\r
-            const bool usingManagedParameters = (audioProcessor.getParameters().size() == numParameters);\r
+            const bool forceLegacyParamIDs = false;\r
            #endif\r
 \r
-            for (int parameterIndex = 0; parameterIndex < numParameters; ++parameterIndex)\r
+            auto bypassPartOfRegularParams = isBypassPartOfRegularParemeters();\r
+\r
+            juceParameters.update (audioProcessor, forceLegacyParamIDs);\r
+\r
+            bool aaxWrapperProvidedBypassParam = false;\r
+            auto* bypassParameter = pluginInstance->getBypassParameter();\r
+\r
+            if (bypassParameter == nullptr)\r
+            {\r
+                aaxWrapperProvidedBypassParam = true;\r
+\r
+                ownedBypassParameter = new AudioParameterBool (cDefaultMasterBypassID, "Master Bypass", false, {}, {}, {});\r
+\r
+                bypassParameter = ownedBypassParameter;\r
+            }\r
+\r
+            if (! bypassPartOfRegularParams)\r
+                juceParameters.params.add (bypassParameter);\r
+\r
+            int parameterIndex = 0;\r
+\r
+            for (auto* juceParam : juceParameters.params)\r
             {\r
-                auto category = audioProcessor.getParameterCategory (parameterIndex);\r
+                auto isBypassParameter = (juceParam == bypassParameter);\r
 \r
-                aaxParamIDs.add (usingManagedParameters ? audioProcessor.getParameterID (parameterIndex)\r
-                                                        : String (parameterIndex));\r
+                auto category = juceParam->getCategory();\r
+                auto paramID  = isBypassParameter ? String (cDefaultMasterBypassID)\r
+                                                  : juceParameters.getParamID (audioProcessor, parameterIndex);\r
 \r
-                auto paramID = aaxParamIDs.getReference (parameterIndex).getCharPointer();\r
+                aaxParamIDs.add (paramID);\r
+                auto aaxParamID = aaxParamIDs.getReference (parameterIndex++).getCharPointer();\r
 \r
-                paramMap.set (AAXClasses::getAAXParamHash (paramID), parameterIndex);\r
+\r
+                paramMap.set (AAXClasses::getAAXParamHash (aaxParamID), juceParam);\r
 \r
                 // is this a meter?\r
                 if (((category & 0xffff0000) >> 16) == 2)\r
                 {\r
-                    aaxMeters.add (parameterIndex);\r
+                    aaxMeters.add (juceParam);\r
                     continue;\r
                 }\r
 \r
-                auto parameter = new AAX_CParameter<float> (paramID,\r
-                                                            AAX_CString (audioProcessor.getParameterName (parameterIndex, 31).toRawUTF8()),\r
-                                                            audioProcessor.getParameterDefaultValue (parameterIndex),\r
+                auto parameter = new AAX_CParameter<float> (aaxParamID,\r
+                                                            AAX_CString (juceParam->getName (31).toRawUTF8()),\r
+                                                            juceParam->getDefaultValue(),\r
                                                             AAX_CLinearTaperDelegate<float, 0>(),\r
                                                             AAX_CNumberDisplayDelegate<float, 3>(),\r
-                                                            audioProcessor.isParameterAutomatable (parameterIndex));\r
+                                                            juceParam->isAutomatable());\r
 \r
-                parameter->AddShortenedName (audioProcessor.getParameterName (parameterIndex, 4).toRawUTF8());\r
+                parameter->AddShortenedName (juceParam->getName (4).toRawUTF8());\r
 \r
-                auto parameterNumSteps = audioProcessor.getParameterNumSteps (parameterIndex);\r
+                auto parameterNumSteps = juceParam->getNumSteps();\r
                 parameter->SetNumberOfSteps ((uint32_t) parameterNumSteps);\r
 \r
                #if JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE\r
                 parameter->SetType (parameterNumSteps > 1000 ? AAX_eParameterType_Continuous\r
                                                              : AAX_eParameterType_Discrete);\r
                #else\r
-                parameter->SetType (audioProcessor.isParameterDiscrete (parameterIndex) ? AAX_eParameterType_Discrete\r
-                                                                                        : AAX_eParameterType_Continuous);\r
+                parameter->SetType (juceParam->isDiscrete() ? AAX_eParameterType_Discrete\r
+                                                            : AAX_eParameterType_Continuous);\r
                #endif\r
 \r
-                parameter->SetOrientation (audioProcessor.isParameterOrientationInverted (parameterIndex)\r
+                parameter->SetOrientation (juceParam->isOrientationInverted()\r
                                             ? (AAX_eParameterOrientation_RightMinLeftMax | AAX_eParameterOrientation_TopMinBottomMax\r
                                                 | AAX_eParameterOrientation_RotarySingleDotMode | AAX_eParameterOrientation_RotaryRightMinLeftMax)\r
                                             : (AAX_eParameterOrientation_LeftMinRightMax | AAX_eParameterOrientation_BottomMinTopMax\r
                                                 | AAX_eParameterOrientation_RotarySingleDotMode | AAX_eParameterOrientation_RotaryLeftMinRightMax));\r
 \r
                 mParameterManager.AddParameter (parameter);\r
+\r
+                if (isBypassParameter)\r
+                    mPacketDispatcher.RegisterPacket (aaxParamID, JUCEAlgorithmIDs::bypass);\r
             }\r
         }\r
 \r
@@ -1696,7 +1707,10 @@ namespace AAXClasses
         //==============================================================================\r
         inline int getParamIndexFromID (AAX_CParamID paramID) const noexcept\r
         {\r
-            return paramMap [AAXClasses::getAAXParamHash (paramID)];\r
+            if (auto* param = getParameterFromID (paramID))\r
+                return LegacyAudioParameter::getParamIndex (getPluginInstance(), param);\r
+\r
+            return -1;\r
         }\r
 \r
         inline AAX_CParamID getAAXParamIDFromJuceIndex (int index) const noexcept\r
@@ -1707,6 +1721,11 @@ namespace AAXClasses
             return nullptr;\r
         }\r
 \r
+        AudioProcessorParameter* getParameterFromID (AAX_CParamID paramID) const noexcept\r
+        {\r
+            return paramMap [AAXClasses::getAAXParamHash (paramID)];\r
+        }\r
+\r
         //==============================================================================\r
         static AudioProcessor::BusesLayout getDefaultLayout (const AudioProcessor& p, bool enableAll)\r
         {\r
@@ -1757,9 +1776,11 @@ namespace AAXClasses
         Array<int> inputLayoutMap, outputLayoutMap;\r
 \r
         Array<String> aaxParamIDs;\r
-        HashMap<int32, int> paramMap;\r
+        HashMap<int32, AudioProcessorParameter*> paramMap;\r
+        LegacyAudioParametersWrapper juceParameters;\r
+        ScopedPointer<AudioProcessorParameter> ownedBypassParameter;\r
 \r
-        Array<int> aaxMeters;\r
+        Array<AudioProcessorParameter*> aaxMeters;\r
 \r
         struct ChunkMemoryBlock\r
         {\r
@@ -1835,12 +1856,21 @@ namespace AAXClasses
     //==============================================================================\r
     static int addAAXMeters (AudioProcessor& p, AAX_IEffectDescriptor& descriptor)\r
     {\r
-        const int n = p.getNumParameters();\r
+        LegacyAudioParametersWrapper params;\r
+\r
+       #if JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
+        const bool forceLegacyParamIDs = true;\r
+       #else\r
+        const bool forceLegacyParamIDs = false;\r
+       #endif\r
+\r
+        params.update (p, forceLegacyParamIDs);\r
+\r
         int meterIdx = 0;\r
 \r
-        for (int i = 0; i < n; ++i)\r
+        for (auto* param : params.params)\r
         {\r
-            auto category = p.getParameterCategory (i);\r
+            auto category = param->getCategory();\r
 \r
             // is this a meter?\r
             if (((category & 0xffff0000) >> 16) == 2)\r
@@ -1851,7 +1881,7 @@ namespace AAXClasses
                     meterProperties->AddProperty (AAX_eProperty_Meter_Orientation, AAX_eMeterOrientation_TopRight);\r
 \r
                     descriptor.AddMeterDescription ('Metr' + static_cast<AAX_CTypeID> (meterIdx++),\r
-                                                    p.getParameterName (i).toRawUTF8(), meterProperties);\r
+                                                    param->getName (1024).toRawUTF8(), meterProperties);\r
                 }\r
             }\r
         }\r
index 8831d6263f11f4c6240e4382588d2e2fb3dd4baa..152566e4a34c4d3c13d2aebaede8a5c4a82081ba 100644 (file)
@@ -79,6 +79,7 @@
 #include "../utility/juce_FakeMouseMoveGenerator.h"\r
 #include "../utility/juce_WindowsHooks.h"\r
 \r
+#include "../../juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp"\r
 #include "../../juce_audio_processors/format_types/juce_VSTCommon.h"\r
 \r
 #ifdef _MSC_VER\r
@@ -222,7 +223,8 @@ struct AbletonLiveHostSpecific
 class JuceVSTWrapper  : public AudioProcessorListener,\r
                         public AudioPlayHead,\r
                         private Timer,\r
-                        private AsyncUpdater\r
+                        private AsyncUpdater,\r
+                        private AudioProcessorParameter::Listener\r
 {\r
 private:\r
     //==============================================================================\r
@@ -260,6 +262,8 @@ public:
        : hostCallback (cb),\r
          processor (af)\r
     {\r
+        inParameterChangedCallback = false;\r
+\r
         // VST-2 does not support disabling buses: so always enable all of them\r
         processor->enableAllBuses();\r
 \r
@@ -279,6 +283,11 @@ public:
         processor->setPlayHead (this);\r
         processor->addListener (this);\r
 \r
+        if (auto* juceParam = processor->getBypassParameter())\r
+            juceParam->addListener (this);\r
+\r
+        juceParameters.update (*processor, false);\r
+\r
         memset (&vstEffect, 0, sizeof (vstEffect));\r
         vstEffect.interfaceIdentifier = juceVstInterfaceIdentifier;\r
         vstEffect.dispatchFunction = dispatcherCB;\r
@@ -286,7 +295,7 @@ public:
         vstEffect.setParameterValueFunction = setParameterCB;\r
         vstEffect.getParameterValueFunction = getParameterCB;\r
         vstEffect.numPrograms = jmax (1, af->getNumPrograms());\r
-        vstEffect.numParameters = af->getNumParameters();\r
+        vstEffect.numParameters = juceParameters.getNumParameters();\r
         vstEffect.numInputChannels = maxNumInChannels;\r
         vstEffect.numOutputChannels = maxNumOutChannels;\r
         vstEffect.latency = processor->getLatencySamples();\r
@@ -704,11 +713,10 @@ public:
     //==============================================================================\r
     float getParameter (int32 index) const\r
     {\r
-        if (processor == nullptr)\r
-            return 0.0f;\r
+        if (auto* param = juceParameters.getParamForIndex (index))\r
+            return param->getValue();\r
 \r
-        jassert (isPositiveAndBelow (index, processor->getNumParameters()));\r
-        return processor->getParameter (index);\r
+        return 0.0f;\r
     }\r
 \r
     static float getParameterCB (VstEffectInterface* vstInterface, int32 index)\r
@@ -718,18 +726,12 @@ public:
 \r
     void setParameter (int32 index, float value)\r
     {\r
-        if (processor != nullptr)\r
+        if (auto* param = juceParameters.getParamForIndex (index))\r
         {\r
-            if (auto* param = processor->getParameters()[index])\r
-            {\r
-                param->setValue (value);\r
-                param->sendValueChangedMessageToListeners (value);\r
-            }\r
-            else\r
-            {\r
-                jassert (isPositiveAndBelow (index, processor->getNumParameters()));\r
-                processor->setParameter (index, value);\r
-            }\r
+            param->setValue (value);\r
+\r
+            inParameterChangedCallback = true;\r
+            param->sendValueChangedMessageToListeners (value);\r
         }\r
     }\r
 \r
@@ -740,6 +742,12 @@ public:
 \r
     void audioProcessorParameterChanged (AudioProcessor*, int index, float newValue) override\r
     {\r
+        if (inParameterChangedCallback.get())\r
+        {\r
+            inParameterChangedCallback = false;\r
+            return;\r
+        }\r
+\r
         if (hostCallback != nullptr)\r
             hostCallback (&vstEffect, hostOpcodeParameterChanged, index, 0, 0, newValue);\r
     }\r
@@ -756,6 +764,14 @@ public:
             hostCallback (&vstEffect, hostOpcodeParameterChangeGestureEnd, index, 0, 0, 0);\r
     }\r
 \r
+    void parameterValueChanged (int, float newValue) override\r
+    {\r
+        // this can only come from the bypass parameter\r
+        isBypassed = (newValue != 0.0f);\r
+    }\r
+\r
+    void parameterGestureChanged (int, bool) override {}\r
+\r
     void audioProcessorChanged (AudioProcessor*) override\r
     {\r
         vstEffect.latency = processor->getLatencySamples();\r
@@ -1272,10 +1288,12 @@ public:
             if (auto* ed = getEditorComp())\r
             {\r
                 ed->setTopLeftPosition (0, 0);\r
-                ed->setBounds (ed->getLocalArea (this, getLocalBounds()));\r
+\r
+                if (shouldResizeEditor)\r
+                    ed->setBounds (ed->getLocalArea (this, getLocalBounds()));\r
 \r
                 if (! getHostType().isBitwigStudio())\r
-                    updateWindowSize();\r
+                    updateWindowSize (false);\r
             }\r
 \r
            #if JUCE_MAC && ! JUCE_64BIT\r
@@ -1286,7 +1304,7 @@ public:
 \r
         void childBoundsChanged (Component*) override\r
         {\r
-            updateWindowSize();\r
+            updateWindowSize (false);\r
         }\r
 \r
         juce::Rectangle<int> getSizeToContainChild()\r
@@ -1297,7 +1315,7 @@ public:
             return {};\r
         }\r
 \r
-        void updateWindowSize()\r
+        void updateWindowSize (bool resizeEditor)\r
         {\r
             if (! isInSizeWindow)\r
             {\r
@@ -1314,8 +1332,14 @@ public:
                     resizeHostWindow (pos.getWidth(), pos.getHeight());\r
 \r
                    #if ! JUCE_LINUX // setSize() on linux causes renoise and energyxt to fail.\r
+                    if (! resizeEditor) // this is needed to prevent an infinite resizing loop due to coordinate rounding\r
+                        shouldResizeEditor = false;\r
+\r
                     setSize (pos.getWidth(), pos.getHeight());\r
+\r
+                    shouldResizeEditor = true;\r
                    #else\r
+                    ignoreUnused (resizeEditor);\r
                     XResizeWindow (display.display, (Window) getWindowHandle(), pos.getWidth(), pos.getHeight());\r
                    #endif\r
 \r
@@ -1433,6 +1457,7 @@ public:
         JuceVSTWrapper& wrapper;\r
         FakeMouseMoveGenerator fakeMouseGenerator;\r
         bool isInSizeWindow = false;\r
+        bool shouldResizeEditor = true;\r
 \r
        #if JUCE_MAC\r
         void* hostWindow = {};\r
@@ -1462,6 +1487,8 @@ private:
     VSTMidiEventList outgoingEvents;\r
     float editorScaleFactor = 1.0f;\r
 \r
+    LegacyAudioParametersWrapper juceParameters;\r
+\r
     bool isProcessing = false, isBypassed = false, hasShutdown = false;\r
     bool firstProcessCallback = true, shouldDeleteEditor = false;\r
 \r
@@ -1477,6 +1504,8 @@ private:
 \r
     HeapBlock<VstSpeakerConfiguration> cachedInArrangement, cachedOutArrangement;\r
 \r
+    ThreadLocalValue<bool> inParameterChangedCallback;\r
+\r
     static JuceVSTWrapper* getWrapper (VstEffectInterface* v) noexcept  { return static_cast<JuceVSTWrapper*> (v->effectPointer); }\r
 \r
     bool isProcessLevelOffline()\r
@@ -1652,11 +1681,10 @@ private:
 \r
     pointer_sized_int handleGetParameterLabel (VstOpCodeArguments args)\r
     {\r
-        if (processor != nullptr)\r
+        if (auto* param = juceParameters.getParamForIndex (args.index))\r
         {\r
-            jassert (isPositiveAndBelow (args.index, processor->getNumParameters()));\r
             // length should technically be kVstMaxParamStrLen, which is 8, but hosts will normally allow a bit more.\r
-            processor->getParameterLabel (args.index).copyToUTF8 ((char*) args.ptr, 24 + 1);\r
+            param->getLabel().copyToUTF8 ((char*) args.ptr, 24 + 1);\r
         }\r
 \r
         return 0;\r
@@ -1664,11 +1692,10 @@ private:
 \r
     pointer_sized_int handleGetParameterText (VstOpCodeArguments args)\r
     {\r
-        if (processor != nullptr)\r
+        if (auto* param = juceParameters.getParamForIndex (args.index))\r
         {\r
-            jassert (isPositiveAndBelow (args.index, processor->getNumParameters()));\r
             // length should technically be kVstMaxParamStrLen, which is 8, but hosts will normally allow a bit more.\r
-            processor->getParameterText (args.index, 24).copyToUTF8 ((char*) args.ptr, 24 + 1);\r
+            param->getCurrentValueAsText().copyToUTF8 ((char*) args.ptr, 24 + 1);\r
         }\r
 \r
         return 0;\r
@@ -1676,11 +1703,10 @@ private:
 \r
     pointer_sized_int handleGetParameterName (VstOpCodeArguments args)\r
     {\r
-        if (processor != nullptr)\r
+        if (auto* param = juceParameters.getParamForIndex (args.index))\r
         {\r
-            jassert (isPositiveAndBelow (args.index, processor->getNumParameters()));\r
             // length should technically be kVstMaxParamStrLen, which is 8, but hosts will normally allow a bit more.\r
-            processor->getParameterName (args.index, 32).copyToUTF8 ((char*) args.ptr, 32 + 1);\r
+            param->getName (32).copyToUTF8 ((char*) args.ptr, 32 + 1);\r
         }\r
 \r
         return 0;\r
@@ -1811,23 +1837,25 @@ private:
 \r
     pointer_sized_int handleIsParameterAutomatable (VstOpCodeArguments args)\r
     {\r
-        if (processor == nullptr)\r
-            return 0;\r
+        if (auto* param = juceParameters.getParamForIndex (args.index))\r
+        {\r
+            const bool isMeter = (((param->getCategory() & 0xffff0000) >> 16) == 2);\r
+            return (param->isAutomatable() && (! isMeter) ? 1 : 0);\r
+        }\r
 \r
-        const bool isMeter = (((processor->getParameterCategory (args.index) & 0xffff0000) >> 16) == 2);\r
-        return (processor->isParameterAutomatable (args.index) && (! isMeter) ? 1 : 0);\r
+        return 0;\r
     }\r
 \r
     pointer_sized_int handleParameterValueForText (VstOpCodeArguments args)\r
     {\r
-        if (processor != nullptr)\r
+        if (auto* param = juceParameters.getParamForIndex (args.index))\r
         {\r
-            jassert (isPositiveAndBelow (args.index, processor->getNumParameters()));\r
-\r
-            if (auto* param = processor->getParameters()[args.index])\r
+            if (! LegacyAudioParameter::isLegacy (param))\r
             {\r
                 auto value = param->getValueForText (String::fromUTF8 ((char*) args.ptr));\r
                 param->setValue (value);\r
+\r
+                inParameterChangedCallback = true;\r
                 param->sendValueChangedMessageToListeners (value);\r
 \r
                 return 1;\r
@@ -1914,6 +1942,10 @@ private:
     pointer_sized_int handleSetBypass (VstOpCodeArguments args)\r
     {\r
         isBypassed = (args.value != 0);\r
+\r
+        if (auto* bypass = processor->getBypassParameter())\r
+            bypass->setValueNotifyingHost (isBypassed ? 1.0f : 0.0f);\r
+\r
         return 1;\r
     }\r
 \r
@@ -2092,7 +2124,7 @@ private:
                     ed->setScaleFactor (editorScaleFactor);\r
 \r
                 if (editorComp != nullptr)\r
-                    editorComp->updateWindowSize();\r
+                    editorComp->updateWindowSize (true);\r
             }\r
            #endif\r
         }\r
@@ -2106,11 +2138,14 @@ private:
     {\r
         if (processor != nullptr && dest != nullptr)\r
         {\r
-            if (auto* param = processor->getParameters()[(int) paramIndex])\r
+            if (auto* param = juceParameters.getParamForIndex ((int) paramIndex))\r
             {\r
-                String text (param->getText (value, 1024));\r
-                memcpy (dest, text.toRawUTF8(), ((size_t) text.length()) + 1);\r
-                return 0xbeef;\r
+                if (! LegacyAudioParameter::isLegacy (param))\r
+                {\r
+                    String text (param->getText (value, 1024));\r
+                    memcpy (dest, text.toRawUTF8(), ((size_t) text.length()) + 1);\r
+                    return 0xbeef;\r
+                }\r
             }\r
         }\r
 \r
index 135c232e965cafbc8f77db85b95c02ed046bd9cd..614d1f02bce258798cf957ce880c4418492c0865 100644 (file)
@@ -42,6 +42,7 @@
 #include "../utility/juce_IncludeModuleHeaders.h"\r
 #include "../utility/juce_WindowsHooks.h"\r
 #include "../utility/juce_FakeMouseMoveGenerator.h"\r
+#include "../../juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp"\r
 #include "../../juce_audio_processors/format_types/juce_VST3Common.h"\r
 \r
 #ifndef JUCE_VST3_CAN_REPLACE_VST2\r
@@ -89,7 +90,12 @@ using namespace Steinberg;
 class JuceAudioProcessor  : public FUnknown\r
 {\r
 public:\r
-    JuceAudioProcessor (AudioProcessor* source) noexcept  : audioProcessor (source) {}\r
+    JuceAudioProcessor (AudioProcessor* source) noexcept\r
+         : audioProcessor (source)\r
+    {\r
+        setupParameters();\r
+    }\r
+\r
     virtual ~JuceAudioProcessor() {}\r
 \r
     AudioProcessor* get() const noexcept      { return audioProcessor; }\r
@@ -97,26 +103,142 @@ public:
     JUCE_DECLARE_VST3_COM_QUERY_METHODS\r
     JUCE_DECLARE_VST3_COM_REF_METHODS\r
 \r
-    static const FUID iid;\r
+    //==============================================================================\r
+    #if JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
+    inline Vst::ParamID getVSTParamIDForIndex (int paramIndex) const noexcept   { return static_cast<Vst::ParamID> (paramIndex); }\r
+   #else\r
+    inline Vst::ParamID getVSTParamIDForIndex (int paramIndex) const noexcept\r
+    {\r
+        return isUsingManagedParameters() ? vstParamIDs.getReference (paramIndex)\r
+                                          : static_cast<Vst::ParamID> (paramIndex);\r
+    }\r
+   #endif\r
+\r
+    AudioProcessorParameter* getParamForVSTParamID (Vst::ParamID paramID) const noexcept\r
+    {\r
+        return paramMap[static_cast<int32> (paramID)];\r
+    }\r
 \r
-    bool isBypassed = false;\r
+    AudioProcessorParameter* getBypassParameter() const noexcept\r
+    {\r
+        return getParamForVSTParamID (bypassParamID);\r
+    }\r
+\r
+    int getNumParameters() const noexcept             { return vstParamIDs.size(); }\r
+    bool isUsingManagedParameters() const noexcept    { return juceParameters.isUsingManagedParameters(); }\r
+\r
+    //==============================================================================\r
+    static const FUID iid;\r
+    Array<Vst::ParamID> vstParamIDs;\r
+    Vst::ParamID bypassParamID = 0;\r
+    bool bypassIsRegularParameter = false;\r
 \r
 private:\r
+    enum InternalParameters\r
+    {\r
+        paramBypass               = 0x62797073 // 'byps'\r
+    };\r
+\r
+    //==============================================================================\r
+    bool isBypassPartOfRegularParemeters() const\r
+    {\r
+        int n = juceParameters.getNumParameters();\r
+\r
+        if (auto* bypassParam = audioProcessor->getBypassParameter())\r
+            for (int i = 0; i < n; ++i)\r
+                if (juceParameters.getParamForIndex (i) == bypassParam)\r
+                    return true;\r
+\r
+        return false;\r
+    }\r
+\r
+    void setupParameters()\r
+    {\r
+       #if JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
+        const bool forceLegacyParamIDs = true;\r
+       #else\r
+        const bool forceLegacyParamIDs = false;\r
+       #endif\r
+\r
+        juceParameters.update (*audioProcessor, forceLegacyParamIDs);\r
+        auto numParameters = juceParameters.getNumParameters();\r
+\r
+        bool vst3WrapperProvidedBypassParam = false;\r
+        auto* bypassParameter = audioProcessor->getBypassParameter();\r
+\r
+        if (bypassParameter == nullptr)\r
+        {\r
+            vst3WrapperProvidedBypassParam = true;\r
+            bypassParameter = ownedBypassParameter = new AudioParameterBool ("byps", "Bypass", false, {}, {}, {});\r
+        }\r
+\r
+        // if the bypass parameter is not part of the exported parameters that the plug-in supports\r
+        // then add it to the end of the list as VST3 requires the bypass parameter to be exported!\r
+        bypassIsRegularParameter = isBypassPartOfRegularParemeters();\r
+\r
+        if (! bypassIsRegularParameter)\r
+            juceParameters.params.add (bypassParameter);\r
+\r
+        int i = 0;\r
+        for (auto* juceParam : juceParameters.params)\r
+        {\r
+            bool isBypassParameter = (juceParam == bypassParameter);\r
+\r
+            Vst::ParamID vstParamID = forceLegacyParamIDs ? static_cast<Vst::ParamID> (i++)\r
+                                                          : generateVSTParamIDForParam (juceParam);\r
+\r
+            if (isBypassParameter)\r
+            {\r
+                // we need to remain backward compatible with the old bypass id\r
+                if (vst3WrapperProvidedBypassParam)\r
+                    vstParamID = static_cast<Vst::ParamID> (isUsingManagedParameters() ? paramBypass : numParameters);\r
+\r
+                bypassParamID = vstParamID;\r
+            }\r
+\r
+            vstParamIDs.add (vstParamID);\r
+            paramMap.set (static_cast<int32> (vstParamID), juceParam);\r
+        }\r
+    }\r
+\r
+    Vst::ParamID generateVSTParamIDForParam (AudioProcessorParameter* param)\r
+    {\r
+        auto juceParamID = LegacyAudioParameter::getParamID (param, false);\r
+        auto paramHash = static_cast<Vst::ParamID> (juceParamID.hashCode());\r
+\r
+       #if JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS\r
+        // studio one doesn't like negative parameters\r
+        paramHash &= ~(1 << (sizeof (Vst::ParamID) * 8 - 1));\r
+       #endif\r
+\r
+        return isUsingManagedParameters() ? paramHash\r
+                                          : static_cast<Vst::ParamID> (juceParamID.getIntValue());\r
+    }\r
+\r
+    //==============================================================================\r
     Atomic<int> refCount;\r
     ScopedPointer<AudioProcessor> audioProcessor;\r
     ScopedJuceInitialiser_GUI libraryInitialiser;\r
 \r
+    //==============================================================================\r
+    LegacyAudioParametersWrapper juceParameters;\r
+    HashMap<int32, AudioProcessorParameter*> paramMap;\r
+    ScopedPointer<AudioProcessorParameter> ownedBypassParameter;\r
+\r
     JuceAudioProcessor() = delete;\r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceAudioProcessor)\r
 };\r
 \r
 class JuceVST3Component;\r
 \r
+static ThreadLocalValue<bool> inParameterChangedCallback;\r
+\r
 //==============================================================================\r
 class JuceVST3EditController : public Vst::EditController,\r
                                public Vst::IMidiMapping,\r
                                public Vst::ChannelContext::IInfoListener,\r
-                               public AudioProcessorListener\r
+                               public AudioProcessorListener,\r
+                               private AudioProcessorParameter::Listener\r
 {\r
 public:\r
     JuceVST3EditController (Vst::IHostApplication* host)\r
@@ -195,39 +317,41 @@ public:
     enum InternalParameters\r
     {\r
         paramPreset               = 0x70727374, // 'prst'\r
-        paramBypass               = 0x62797073, // 'byps'\r
         paramMidiControllerOffset = 0x6d636d00  // 'mdm*'\r
     };\r
 \r
     struct Param  : public Vst::Parameter\r
     {\r
-        Param (AudioProcessor& p, int index, Vst::ParamID paramID)  : owner (p), paramIndex (index)\r
+        Param (JuceVST3EditController& editController, AudioProcessorParameter& p,\r
+               Vst::ParamID vstParamID, bool isBypassParameter, bool forceLegacyParamIDs)\r
+            : owner (editController), param (p)\r
         {\r
-            info.id = paramID;\r
+            info.id = vstParamID;\r
 \r
-            toString128 (info.title, p.getParameterName (index));\r
-            toString128 (info.shortTitle, p.getParameterName (index, 8));\r
-            toString128 (info.units, p.getParameterLabel (index));\r
+            toString128 (info.title,      param.getName (128));\r
+            toString128 (info.shortTitle, param.getName (8));\r
+            toString128 (info.units,      param.getLabel());\r
 \r
             info.stepCount = (Steinberg::int32) 0;\r
 \r
-           #if ! JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE\r
-            if (p.isParameterDiscrete (index))\r
-           #endif\r
+            if (! forceLegacyParamIDs && param.isDiscrete())\r
             {\r
-                const int numSteps = p.getParameterNumSteps (index);\r
+                const int numSteps = param.getNumSteps();\r
                 info.stepCount = (Steinberg::int32) (numSteps > 0 && numSteps < 0x7fffffff ? numSteps - 1 : 0);\r
             }\r
 \r
-            info.defaultNormalizedValue = p.getParameterDefaultValue (index);\r
+            info.defaultNormalizedValue = param.getDefaultValue();\r
             jassert (info.defaultNormalizedValue >= 0 && info.defaultNormalizedValue <= 1.0f);\r
             info.unitId = Vst::kRootUnitId;\r
 \r
             // Is this a meter?\r
-            if (((p.getParameterCategory (index) & 0xffff0000) >> 16) == 2)\r
+            if (((param.getCategory() & 0xffff0000) >> 16) == 2)\r
                 info.flags = Vst::ParameterInfo::kIsReadOnly;\r
             else\r
-                info.flags = p.isParameterAutomatable (index) ? Vst::ParameterInfo::kCanAutomate : 0;\r
+                info.flags = param.isAutomatable() ? Vst::ParameterInfo::kCanAutomate : 0;\r
+\r
+            if (isBypassParameter)\r
+                info.flags |= Vst::ParameterInfo::kIsBypass;\r
 \r
             valueNormalized = info.defaultNormalizedValue;\r
         }\r
@@ -249,15 +373,10 @@ public:
                 {\r
                     auto value = static_cast<float> (v);\r
 \r
-                    if (auto* param = owner.getParameters()[paramIndex])\r
-                    {\r
-                        param->setValue (value);\r
-                        param->sendValueChangedMessageToListeners (value);\r
-                    }\r
-                    else\r
-                    {\r
-                        owner.setParameter (paramIndex, value);\r
-                    }\r
+                    param.setValue (value);\r
+\r
+                    inParameterChangedCallback = true;\r
+                    param.sendValueChangedMessageToListeners (value);\r
                 }\r
 \r
                 changed();\r
@@ -269,18 +388,14 @@ public:
 \r
         void toString (Vst::ParamValue value, Vst::String128 result) const override\r
         {\r
-            if (auto* p = owner.getParameters()[paramIndex])\r
-                toString128 (result, p->getText ((float) value, 128));\r
-            else\r
-                // remain backward-compatible with old JUCE code\r
-                toString128 (result, owner.getParameterText (paramIndex, 128));\r
+            toString128 (result, param.getText ((float) value, 128));\r
         }\r
 \r
         bool fromString (const Vst::TChar* text, Vst::ParamValue& outValueNormalized) const override\r
         {\r
-            if (auto* p = owner.getParameters()[paramIndex])\r
+            if (! LegacyAudioParameter::isLegacy (&param))\r
             {\r
-                outValueNormalized = p->getValueForText (getStringFromVstTChars (text));\r
+                outValueNormalized = param.getValueForText (getStringFromVstTChars (text));\r
                 return true;\r
             }\r
 \r
@@ -296,94 +411,12 @@ public:
         Vst::ParamValue toNormalized (Vst::ParamValue v) const override  { return v; }\r
 \r
     private:\r
-        AudioProcessor& owner;\r
-        int paramIndex;\r
+        JuceVST3EditController& owner;\r
+        AudioProcessorParameter& param;\r
 \r
         JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Param)\r
     };\r
 \r
-    //==============================================================================\r
-    struct BypassParam  : public Vst::Parameter\r
-    {\r
-        BypassParam (Vst::ParamID vstParamID)\r
-        {\r
-            info.id = vstParamID;\r
-            toString128 (info.title, "Bypass");\r
-            toString128 (info.shortTitle, "Bypass");\r
-            toString128 (info.units, "");\r
-            info.stepCount = 1;\r
-            info.defaultNormalizedValue = 0.0f;\r
-            info.unitId = Vst::kRootUnitId;\r
-            info.flags = Vst::ParameterInfo::kIsBypass | Vst::ParameterInfo::kCanAutomate;\r
-        }\r
-\r
-        virtual ~BypassParam() {}\r
-\r
-        bool setNormalized (Vst::ParamValue v) override\r
-        {\r
-            bool bypass = (v != 0.0f);\r
-            v = (bypass ? 1.0f : 0.0f);\r
-\r
-            if (valueNormalized != v)\r
-            {\r
-                valueNormalized = v;\r
-                changed();\r
-                return true;\r
-            }\r
-\r
-            return false;\r
-        }\r
-\r
-        void toString (Vst::ParamValue value, Vst::String128 result) const override\r
-        {\r
-            bool bypass = (value != 0.0f);\r
-            toString128 (result, bypass ? "On" : "Off");\r
-        }\r
-\r
-        bool fromString (const Vst::TChar* text, Vst::ParamValue& outValueNormalized) const override\r
-        {\r
-            auto paramValueString = getStringFromVstTChars (text);\r
-\r
-            if (paramValueString.equalsIgnoreCase ("on")\r
-                 || paramValueString.equalsIgnoreCase ("yes")\r
-                 || paramValueString.equalsIgnoreCase ("true"))\r
-            {\r
-                outValueNormalized = 1.0f;\r
-                return true;\r
-            }\r
-\r
-            if (paramValueString.equalsIgnoreCase ("off")\r
-                 || paramValueString.equalsIgnoreCase ("no")\r
-                 || paramValueString.equalsIgnoreCase ("false"))\r
-            {\r
-                outValueNormalized = 0.0f;\r
-                return true;\r
-            }\r
-\r
-            var varValue = JSON::fromString (paramValueString);\r
-\r
-            if (varValue.isDouble() || varValue.isInt()\r
-                 || varValue.isInt64() || varValue.isBool())\r
-            {\r
-                double value = varValue;\r
-                outValueNormalized = (value != 0.0) ? 1.0f : 0.0f;\r
-                return true;\r
-            }\r
-\r
-            return false;\r
-        }\r
-\r
-        static String getStringFromVstTChars (const Vst::TChar* text)\r
-        {\r
-            return juce::String (juce::CharPointer_UTF16 (reinterpret_cast<const juce::CharPointer_UTF16::CharType*> (text)));\r
-        }\r
-\r
-        Vst::ParamValue toPlain (Vst::ParamValue v) const override       { return v; }\r
-        Vst::ParamValue toNormalized (Vst::ParamValue v) const override  { return v; }\r
-\r
-        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BypassParam)\r
-    };\r
-\r
     //==============================================================================\r
     struct ProgramChangeParameter  : public Vst::Parameter\r
     {\r
@@ -498,12 +531,8 @@ public:
         // Cubase and Nuendo need to inform the host of the current parameter values\r
         if (auto* pluginInstance = getPluginInstance())\r
         {\r
-            auto numParameters = pluginInstance->getNumParameters();\r
-\r
-            for (int i = 0; i < numParameters; ++i)\r
-                setParamNormalized (getVSTParamIDForIndex (i), (double) pluginInstance->getParameter (i));\r
-\r
-            setParamNormalized (bypassParamID, audioProcessor->isBypassed ? 1.0f : 0.0f);\r
+            for (auto vstParamId : audioProcessor->vstParamIDs)\r
+                setParamNormalized (vstParamId, audioProcessor->getParamForVSTParamID (vstParamId)->getValue());\r
 \r
             auto numPrograms = pluginInstance->getNumPrograms();\r
 \r
@@ -597,14 +626,26 @@ public:
     }\r
 \r
     //==============================================================================\r
-    void audioProcessorParameterChangeGestureBegin (AudioProcessor*, int index) override        { beginEdit (getVSTParamIDForIndex (index)); }\r
-    void audioProcessorParameterChangeGestureEnd (AudioProcessor*, int index) override          { endEdit (getVSTParamIDForIndex (index)); }\r
+    void paramChanged (Vst::ParamID vstParamId, float newValue)\r
+    {\r
+        if (inParameterChangedCallback.get())\r
+        {\r
+            inParameterChangedCallback = false;\r
+            return;\r
+        }\r
+\r
+        // NB: Cubase has problems if performEdit is called without setParamNormalized\r
+        EditController::setParamNormalized (vstParamId, (double) newValue);\r
+        performEdit (vstParamId, (double) newValue);\r
+    }\r
+\r
+    //==============================================================================\r
+    void audioProcessorParameterChangeGestureBegin (AudioProcessor*, int index) override        { beginEdit (audioProcessor->getVSTParamIDForIndex (index)); }\r
+    void audioProcessorParameterChangeGestureEnd (AudioProcessor*, int index) override          { endEdit (audioProcessor->getVSTParamIDForIndex (index)); }\r
 \r
     void audioProcessorParameterChanged (AudioProcessor*, int index, float newValue) override\r
     {\r
-        // NB: Cubase has problems if performEdit is called without setParamNormalized\r
-        EditController::setParamNormalized (getVSTParamIDForIndex (index), (double) newValue);\r
-        performEdit (getVSTParamIDForIndex (index), (double) newValue);\r
+        paramChanged (audioProcessor->getVSTParamIDForIndex (index), newValue);\r
     }\r
 \r
     void audioProcessorChanged (AudioProcessor*) override\r
@@ -620,6 +661,19 @@ public:
             componentHandler->restartComponent (Vst::kLatencyChanged | Vst::kParamValuesChanged);\r
     }\r
 \r
+    void parameterValueChanged (int, float newValue) override\r
+    {\r
+        // this can only come from the bypass parameter\r
+        paramChanged (audioProcessor->bypassParamID, newValue);\r
+    }\r
+\r
+    void parameterGestureChanged (int, bool gestureIsStarting) override\r
+    {\r
+        // this can only come from the bypass parameter\r
+        if (gestureIsStarting) beginEdit (audioProcessor->bypassParamID);\r
+        else endEdit (audioProcessor->bypassParamID);\r
+    }\r
+\r
     //==============================================================================\r
     AudioProcessor* getPluginInstance() const noexcept\r
     {\r
@@ -631,6 +685,7 @@ public:
 \r
 private:\r
     friend class JuceVST3Component;\r
+    friend struct Param;\r
 \r
     //==============================================================================\r
     ComSmartPtr<JuceAudioProcessor> audioProcessor;\r
@@ -647,53 +702,45 @@ private:
     Vst::ParamID midiControllerToParameter[numMIDIChannels][Vst::kCountCtrlNumber];\r
 \r
     //==============================================================================\r
-   #if ! JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
-    bool usingManagedParameter = false;\r
-    Array<Vst::ParamID> vstParamIDs;\r
-   #endif\r
-    Vst::ParamID bypassParamID;\r
+    Atomic<int> vst3IsPlaying { 0 };\r
 \r
-    //==============================================================================\r
     void setupParameters()\r
     {\r
         if (auto* pluginInstance = getPluginInstance())\r
         {\r
             pluginInstance->addListener (this);\r
 \r
-           #if JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
-            const bool usingManagedParameter = false;\r
-           #endif\r
+            // as the bypass is not part of the regular parameters\r
+            // we need to listen for it explicitly\r
+            if (! audioProcessor->bypassIsRegularParameter)\r
+                audioProcessor->getBypassParameter()->addListener (this);\r
 \r
             if (parameters.getParameterCount() <= 0)\r
             {\r
-                auto numParameters = pluginInstance->getNumParameters();\r
+                #if JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
+                const bool forceLegacyParamIDs = true;\r
+               #else\r
+                const bool forceLegacyParamIDs = false;\r
+               #endif\r
 \r
-              #if ! JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
-                usingManagedParameter = (pluginInstance->getParameters().size() == numParameters);\r
-              #endif\r
+                auto n = audioProcessor->getNumParameters();\r
 \r
-                for (int i = 0; i < numParameters; ++i)\r
+                for (int i = 0; i < n; ++i)\r
                 {\r
-                   #if JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
-                    const Vst::ParamID vstParamID = static_cast<Vst::ParamID> (i);\r
-                   #else\r
-                    const Vst::ParamID vstParamID = generateVSTParamIDForIndex (pluginInstance, i);\r
-                    vstParamIDs.add (vstParamID);\r
-                   #endif\r
+                    auto vstParamID = audioProcessor->getVSTParamIDForIndex (i);\r
+                    auto* juceParam = audioProcessor->getParamForVSTParamID (vstParamID);\r
 \r
-                    parameters.addParameter (new Param (*pluginInstance, i, vstParamID));\r
+                    parameters.addParameter (new Param (*this, *juceParam, vstParamID,\r
+                                                        (vstParamID == audioProcessor->bypassParamID), forceLegacyParamIDs));\r
                 }\r
 \r
-                bypassParamID = static_cast<Vst::ParamID> (usingManagedParameter ? paramBypass : numParameters);\r
-                parameters.addParameter (new BypassParam (bypassParamID));\r
-\r
                 if (pluginInstance->getNumPrograms() > 1)\r
                     parameters.addParameter (new ProgramChangeParameter (*pluginInstance));\r
             }\r
 \r
            #if JUCE_VST3_EMULATE_MIDI_CC_WITH_PARAMETERS\r
-            parameterToMidiControllerOffset = static_cast<Vst::ParamID> (usingManagedParameter ? paramMidiControllerOffset\r
-                                                                                               : parameters.getParameterCount());\r
+            parameterToMidiControllerOffset = static_cast<Vst::ParamID> (audioProcessor->isUsingManagedParameters() ? paramMidiControllerOffset\r
+                                                                                                                    : parameters.getParameterCount());\r
 \r
             initialiseMidiControllerMappings();\r
            #endif\r
@@ -732,41 +779,6 @@ private:
         }\r
     }\r
 \r
-    //==============================================================================\r
-   #if JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
-    inline Vst::ParamID getVSTParamIDForIndex (int paramIndex) const noexcept   { return static_cast<Vst::ParamID> (paramIndex); }\r
-   #else\r
-    static Vst::ParamID generateVSTParamIDForIndex (AudioProcessor* const pluginFilter, int paramIndex)\r
-    {\r
-        jassert (pluginFilter != nullptr);\r
-\r
-        const int n = pluginFilter->getNumParameters();\r
-        const bool managedParameter = (pluginFilter->getParameters().size() == n);\r
-\r
-        if (isPositiveAndBelow (paramIndex, n))\r
-        {\r
-            auto juceParamID = pluginFilter->getParameterID (paramIndex);\r
-            auto paramHash = static_cast<Vst::ParamID> (juceParamID.hashCode());\r
-\r
-           #if JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS\r
-            // studio one doesn't like negative parameters\r
-            paramHash &= ~(1 << (sizeof (Vst::ParamID) * 8 - 1));\r
-           #endif\r
-\r
-            return managedParameter ? paramHash\r
-                                    : static_cast<Vst::ParamID> (juceParamID.getIntValue());\r
-        }\r
-\r
-        return static_cast<Vst::ParamID> (-1);\r
-    }\r
-\r
-    inline Vst::ParamID getVSTParamIDForIndex (int paramIndex) const noexcept\r
-    {\r
-        return usingManagedParameter ? vstParamIDs.getReference (paramIndex)\r
-                                     : static_cast<Vst::ParamID> (paramIndex);\r
-    }\r
-   #endif\r
-\r
     //==============================================================================\r
     class JuceVST3Editor  : public Vst::EditorView,\r
                             public Steinberg::IPlugViewContentScaleSupport,\r
@@ -1137,6 +1149,8 @@ public:
       : pluginInstance (createPluginFilterOfType (AudioProcessor::wrapperType_VST3)),\r
         host (h)\r
     {\r
+        inParameterChangedCallback = false;\r
+\r
        #ifdef JucePlugin_PreferredChannelConfigurations\r
         short configs[][2] = { JucePlugin_PreferredChannelConfigurations };\r
         const int numConfigs = sizeof (configs) / sizeof (short[2]);\r
@@ -1160,17 +1174,14 @@ public:
         processSetup.sampleRate = 44100.0;\r
         processSetup.symbolicSampleSize = Vst::kSample32;\r
 \r
-       #if JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
-        vstBypassParameterId = static_cast<Vst::ParamID> (pluginInstance->getNumParameters());\r
-       #else\r
-        cacheParameterIDs();\r
-       #endif\r
-\r
         pluginInstance->setPlayHead (this);\r
     }\r
 \r
     ~JuceVST3Component()\r
     {\r
+        if (juceVST3EditController != nullptr)\r
+            juceVST3EditController->vst3IsPlaying = 0;\r
+\r
         if (pluginInstance != nullptr)\r
             if (pluginInstance->getPlayHead() == this)\r
                 pluginInstance->setPlayHead (nullptr);\r
@@ -1234,6 +1245,9 @@ public:
 \r
     tresult PLUGIN_API disconnect (IConnectionPoint*) override\r
     {\r
+        if (juceVST3EditController != nullptr)\r
+            juceVST3EditController->vst3IsPlaying = 0;\r
+\r
         juceVST3EditController = nullptr;\r
         return kResultTrue;\r
     }\r
@@ -1299,24 +1313,50 @@ public:
     tresult PLUGIN_API setIoMode (Vst::IoMode) override                                 { return kNotImplemented; }\r
     tresult PLUGIN_API getRoutingInfo (Vst::RoutingInfo&, Vst::RoutingInfo&) override   { return kNotImplemented; }\r
 \r
-    bool isBypassed()                   { return comPluginInstance->isBypassed; }\r
-    void setBypassed (bool bypassed)    { comPluginInstance->isBypassed = bypassed; }\r
+    //==============================================================================\r
+    bool isBypassed()\r
+    {\r
+        if (auto* bypassParam = comPluginInstance->getBypassParameter())\r
+            return (bypassParam->getValue() != 0.0f);\r
+\r
+        return false;\r
+    }\r
+\r
+    void setBypassed (bool shouldBeBypassed)\r
+    {\r
+        if (auto* bypassParam = comPluginInstance->getBypassParameter())\r
+        {\r
+            auto floatValue = (shouldBeBypassed ? 1.0f : 0.0f);\r
+            bypassParam->setValue (floatValue);\r
+\r
+            inParameterChangedCallback = true;\r
+            bypassParam->sendValueChangedMessageToListeners (floatValue);\r
+        }\r
+    }\r
 \r
     //==============================================================================\r
     void writeJucePrivateStateInformation (MemoryOutputStream& out)\r
     {\r
-        ValueTree privateData (kJucePrivateDataIdentifier);\r
-\r
-        // for now we only store the bypass value\r
-        privateData.setProperty ("Bypass", var (isBypassed()), nullptr);\r
+        if (pluginInstance->getBypassParameter() == nullptr)\r
+        {\r
+            ValueTree privateData (kJucePrivateDataIdentifier);\r
 \r
-        privateData.writeToStream (out);\r
+            // for now we only store the bypass value\r
+            privateData.setProperty ("Bypass", var (isBypassed()), nullptr);\r
+            privateData.writeToStream (out);\r
+        }\r
     }\r
 \r
     void setJucePrivateStateInformation (const void* data, int sizeInBytes)\r
     {\r
-        auto privateData = ValueTree::readFromData (data, static_cast<size_t> (sizeInBytes));\r
-        setBypassed (static_cast<bool> (privateData.getProperty ("Bypass", var (false))));\r
+        if (pluginInstance->getBypassParameter() == nullptr)\r
+        {\r
+            if (auto* bypassParam = comPluginInstance->getBypassParameter())\r
+            {\r
+                auto privateData = ValueTree::readFromData (data, static_cast<size_t> (sizeInBytes));\r
+                setBypassed (static_cast<bool> (privateData.getProperty ("Bypass", var (false))));\r
+            }\r
+        }\r
     }\r
 \r
     void getStateInformation (MemoryBlock& destData)\r
@@ -2008,13 +2048,7 @@ public:
                 {\r
                     auto vstParamID = paramQueue->getParameterId();\r
 \r
-                    if (vstParamID == vstBypassParameterId)\r
-                        setBypassed (static_cast<float> (value) != 0.0f);\r
-                   #if JUCE_VST3_EMULATE_MIDI_CC_WITH_PARAMETERS\r
-                    else if (juceVST3EditController->isMidiControllerParamID (vstParamID))\r
-                        addParameterChangeToMidiBuffer (offsetSamples, vstParamID, value);\r
-                   #endif\r
-                    else if (vstParamID == JuceVST3EditController::paramPreset)\r
+                    if (vstParamID == JuceVST3EditController::paramPreset)\r
                     {\r
                         auto numPrograms  = pluginInstance->getNumPrograms();\r
                         auto programValue = roundToInt (value * (jmax (0, numPrograms - 1)));\r
@@ -2023,20 +2057,21 @@ public:
                              && programValue != pluginInstance->getCurrentProgram())\r
                             pluginInstance->setCurrentProgram (programValue);\r
                     }\r
+                   #if JUCE_VST3_EMULATE_MIDI_CC_WITH_PARAMETERS\r
+                    else if (juceVST3EditController->isMidiControllerParamID (vstParamID))\r
+                        addParameterChangeToMidiBuffer (offsetSamples, vstParamID, value);\r
+                   #endif\r
                     else\r
                     {\r
-                        auto index = getJuceIndexForVSTParamID (vstParamID);\r
                         auto floatValue = static_cast<float> (value);\r
 \r
-                        if (auto* param = pluginInstance->getParameters()[index])\r
+                        if (auto* param = comPluginInstance->getParamForVSTParamID (vstParamID))\r
                         {\r
                             param->setValue (floatValue);\r
+\r
+                            inParameterChangedCallback = true;\r
                             param->sendValueChangedMessageToListeners (floatValue);\r
                         }\r
-                        else if (isPositiveAndBelow (index, pluginInstance->getNumParameters()))\r
-                        {\r
-                            pluginInstance->setParameter (index, floatValue);\r
-                        }\r
                     }\r
                 }\r
             }\r
@@ -2074,12 +2109,16 @@ public:
         if (data.processContext != nullptr)\r
         {\r
             processContext = *data.processContext;\r
-            pluginInstance->vst3IsPlaying = processContext.state & Vst::ProcessContext::kPlaying;\r
+\r
+            if (juceVST3EditController != nullptr)\r
+                juceVST3EditController->vst3IsPlaying = processContext.state & Vst::ProcessContext::kPlaying;\r
         }\r
         else\r
         {\r
             zerostruct (processContext);\r
-            pluginInstance->vst3IsPlaying = 0;\r
+\r
+            if (juceVST3EditController != nullptr)\r
+                juceVST3EditController->vst3IsPlaying = 0;\r
         }\r
 \r
         midiBuffer.clear();\r
@@ -2150,14 +2189,6 @@ private:
    #endif\r
 \r
     ScopedJuceInitialiser_GUI libraryInitialiser;\r
-\r
-   #if ! JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
-    bool usingManagedParameter;\r
-    Array<Vst::ParamID> vstParamIDs;\r
-    HashMap<int32, int> paramMap;\r
-   #endif\r
-    Vst::ParamID vstBypassParameterId;\r
-\r
     static const char* kJucePrivateDataIdentifier;\r
 \r
     //==============================================================================\r
@@ -2373,44 +2404,6 @@ private:
         p.prepareToPlay (sampleRate, bufferSize);\r
     }\r
 \r
-    //==============================================================================\r
-   #if JUCE_FORCE_USE_LEGACY_PARAM_IDS\r
-    inline Vst::ParamID getVSTParamIDForIndex (int paramIndex) const noexcept   { return static_cast<Vst::ParamID> (paramIndex); }\r
-    inline int getJuceIndexForVSTParamID (Vst::ParamID paramID) const noexcept  { return static_cast<int> (paramID); }\r
-   #else\r
-    void cacheParameterIDs()\r
-    {\r
-        const int numParameters = pluginInstance->getNumParameters();\r
-        usingManagedParameter = (pluginInstance->getParameters().size() == numParameters);\r
-\r
-        vstBypassParameterId = static_cast<Vst::ParamID> (usingManagedParameter ? JuceVST3EditController::paramBypass : numParameters);\r
-\r
-        for (int i = 0; i < numParameters; ++i)\r
-        {\r
-            auto paramID = JuceVST3EditController::generateVSTParamIDForIndex (pluginInstance, i);\r
-\r
-            // Consider yourself very unlucky if you hit this assertion. The hash code of your\r
-            // parameter ids are not unique.\r
-            jassert (! vstParamIDs.contains (paramID));\r
-\r
-            vstParamIDs.add (paramID);\r
-            paramMap.set (static_cast<int32> (paramID), i);\r
-        }\r
-    }\r
-\r
-    inline Vst::ParamID getVSTParamIDForIndex (int paramIndex) const noexcept\r
-    {\r
-        return usingManagedParameter ? vstParamIDs.getReference (paramIndex)\r
-                                     : static_cast<Vst::ParamID> (paramIndex);\r
-    }\r
-\r
-    inline int getJuceIndexForVSTParamID (Vst::ParamID paramID) const noexcept\r
-    {\r
-        return usingManagedParameter ? paramMap[static_cast<int32> (paramID)]\r
-                                     : static_cast<int> (paramID);\r
-    }\r
-   #endif\r
-\r
     //==============================================================================\r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceVST3Component)\r
 };\r
index 76af5b85d65daccd26dabe618dd0fbe63db1292c..640f5289e0b93a8f93a456e82b4315304b752fde 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_audio_plugin_client\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE audio plugin wrapper classes\r
   description:      Classes for building VST, VST3, AudioUnit, AAX and RTAS plugins.\r
   website:          http://www.juce.com/juce\r
index ce8129024731a30391c79b882b9a6e9507a2d0b1..725e67439e9c524cd1c5e6ba394b30e29f5d5a35 100644 (file)
@@ -33,6 +33,8 @@
  #pragma clang diagnostic ignored "-Wunused-parameter"\r
  #pragma clang diagnostic ignored "-Wunused"\r
  #pragma clang diagnostic ignored "-Wextra-semi"\r
+ #pragma clang diagnostic ignored "-Wformat-pedantic"\r
+ #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"\r
 #endif\r
 \r
 // From MacOS 10.13 and iOS 11 Apple has (sensibly!) stopped defining a whole\r
index c020008ea95a17a5359ec822aec1fcf1cf4854fb..602bf87cce0ef4712921af280c679c7dc0843285 100644 (file)
@@ -55,13 +55,15 @@ public:
         AbletonLiveGeneric,         /**< Represents Ableton Live. */\r
         AdobeAudition,              /**< Represents Adobe Audition. */\r
         AdobePremierePro,           /**< Represents Adobe Premiere Pro. */\r
+        AppleGarageBand,            /**< Represents Apple GarageBand. */\r
         AppleLogic,                 /**< Represents Apple Logic Pro. */\r
+        AppleMainStage,             /**< Represents Apple Main Stage. */\r
         Ardour,                     /**< Represents Ardour. */\r
+        AvidProTools,               /**< Represents Avid Pro Tools. */\r
         BitwigStudio,               /**< Represents Bitwig Studio. */\r
         CakewalkSonar8,             /**< Represents Cakewalk Sonar 8. */\r
         CakewalkSonarGeneric,       /**< Represents Cakewalk Sonar. */\r
         DaVinciResolve,             /**< Represents DaVinci Resolve. */\r
-        DigidesignProTools,         /**< Represents Avid Pro Tools. */\r
         DigitalPerformer,           /**< Represents Digital Performer. */\r
         FinalCut,                   /**< Represents Apple Final Cut Pro. */\r
         FruityLoops,                /**< Represents Fruity Loops. */\r
@@ -123,14 +125,18 @@ public:
     bool isFinalCut() const noexcept          { return type == FinalCut; }\r
     /** Returns true if the host is Fruity Loops. */\r
     bool isFruityLoops() const noexcept       { return type == FruityLoops; }\r
+    /** Returns true if the host is Apple GarageBand. */\r
+    bool isGarageBand() const noexcept        { return type == AppleGarageBand; }\r
     /** Returns true if the host is Apple Logic Pro. */\r
     bool isLogic() const noexcept             { return type == AppleLogic; }\r
+    /** Returns true if the host is Apple MainStage. */\r
+    bool isMainStage() const noexcept         { return type == AppleMainStage; }\r
     /** Returns true if the host is any version of Steinberg Nuendo. */\r
     bool isNuendo() const noexcept            { return type == SteinbergNuendo3 || type == SteinbergNuendo4  || type == SteinbergNuendo5 ||  type == SteinbergNuendoGeneric; }\r
     /** Returns true if the host is Adobe Premiere Pro. */\r
     bool isPremiere() const noexcept          { return type == AdobePremierePro; }\r
     /** Returns true if the host is Avid Pro Tools. */\r
-    bool isProTools() const noexcept          { return type == DigidesignProTools; }\r
+    bool isProTools() const noexcept          { return type == AvidProTools; }\r
     /** Returns true if the host is Merging Pyramix. */\r
     bool isPyramix() const noexcept           { return type == MergingPyramix; }\r
     /** Returns true if the host is Muse Receptor. */\r
@@ -176,12 +182,15 @@ public:
             case AbletonLiveGeneric:       return "Ableton Live";\r
             case AdobeAudition:            return "Adobe Audition";\r
             case AdobePremierePro:         return "Adobe Premiere";\r
+            case AppleGarageBand:          return "Apple GarageBand";\r
             case AppleLogic:               return "Apple Logic";\r
+            case AppleMainStage:           return "Apple MainStage";\r
+            case Ardour:                   return "Ardour";\r
+            case AvidProTools:             return "ProTools";\r
             case BitwigStudio:             return "Bitwig Studio";\r
             case CakewalkSonar8:           return "Cakewalk Sonar 8";\r
             case CakewalkSonarGeneric:     return "Cakewalk Sonar";\r
             case DaVinciResolve:           return "DaVinci Resolve";\r
-            case DigidesignProTools:       return "ProTools";\r
             case DigitalPerformer:         return "DigitalPerformer";\r
             case FinalCut:                 return "Final Cut";\r
             case FruityLoops:              return "FruityLoops";\r
@@ -213,6 +222,7 @@ public:
             case StudioOne:                return "Studio One";\r
             case Tracktion3:               return "Tracktion 3";\r
             case TracktionGeneric:         return "Tracktion";\r
+            case TracktionWaveform:        return "Tracktion Waveform";\r
             case VBVSTScanner:             return "VBVSTScanner";\r
             case WaveBurner:               return "WaveBurner";\r
             default:                       break;\r
@@ -270,8 +280,10 @@ private:
         if (hostPath.containsIgnoreCase       ("Live 8."))           return AbletonLive8;\r
         if (hostFilename.containsIgnoreCase   ("Live"))              return AbletonLiveGeneric;\r
         if (hostFilename.containsIgnoreCase   ("Adobe Premiere"))    return AdobePremierePro;\r
-        if (hostFilename.contains             ("Logic"))             return AppleLogic;\r
-        if (hostFilename.containsIgnoreCase   ("Pro Tools"))         return DigidesignProTools;\r
+        if (hostFilename.containsIgnoreCase   ("GarageBand"))        return AppleGarageBand;\r
+        if (hostFilename.containsIgnoreCase   ("Logic"))             return AppleLogic;\r
+        if (hostFilename.containsIgnoreCase   ("MainStage"))         return AppleMainStage;\r
+        if (hostFilename.containsIgnoreCase   ("Pro Tools"))         return AvidProTools;\r
         if (hostFilename.containsIgnoreCase   ("Nuendo 3"))          return SteinbergNuendo3;\r
         if (hostFilename.containsIgnoreCase   ("Nuendo 4"))          return SteinbergNuendo4;\r
         if (hostFilename.containsIgnoreCase   ("Nuendo 5"))          return SteinbergNuendo5;\r
@@ -305,10 +317,12 @@ private:
         if (hostFilename.containsIgnoreCase   ("Live "))             return AbletonLiveGeneric;\r
         if (hostFilename.containsIgnoreCase   ("Audition"))          return AdobeAudition;\r
         if (hostFilename.containsIgnoreCase   ("Adobe Premiere"))    return AdobePremierePro;\r
-        if (hostFilename.containsIgnoreCase   ("ProTools"))          return DigidesignProTools;\r
+        if (hostFilename.containsIgnoreCase   ("ProTools"))          return AvidProTools;\r
         if (hostPath.containsIgnoreCase       ("SONAR 8"))           return CakewalkSonar8;\r
         if (hostFilename.containsIgnoreCase   ("SONAR"))             return CakewalkSonarGeneric;\r
+        if (hostFilename.containsIgnoreCase   ("GarageBand"))        return AppleGarageBand;\r
         if (hostFilename.containsIgnoreCase   ("Logic"))             return AppleLogic;\r
+        if (hostFilename.containsIgnoreCase   ("MainStage"))         return AppleMainStage;\r
         if (hostFilename.startsWithIgnoreCase ("Waveform"))          return TracktionWaveform;\r
         if (hostPath.containsIgnoreCase       ("Tracktion 3"))       return Tracktion3;\r
         if (hostFilename.containsIgnoreCase   ("Tracktion"))         return TracktionGeneric;\r
index 938a7d0fd1c31a7c032e0482a684504575803f0b..61943535aaa8a0bf952de631be1dc440eb2df755 100644 (file)
@@ -600,7 +600,7 @@ public:
         }\r
     }\r
 \r
-    // called from the destructer above\r
+    // called from the destructor above\r
     void cleanup()\r
     {\r
        #if JUCE_MAC\r
@@ -1010,10 +1010,20 @@ public:
         for (int i = 0; i < getBusCount (false); ++i)  AudioUnitReset (audioUnit, kAudioUnitScope_Output, static_cast<UInt32> (i));\r
     }\r
 \r
-    void processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages) override\r
+    void processAudio (AudioBuffer<float>& buffer, MidiBuffer& midiMessages, bool processBlockBypassedCalled)\r
     {\r
         auto numSamples = buffer.getNumSamples();\r
 \r
+        if (auSupportsBypass)\r
+        {\r
+            updateBypass (processBlockBypassedCalled);\r
+        }\r
+        else if (processBlockBypassedCalled)\r
+        {\r
+            AudioProcessor::processBlockBypassed (buffer, midiMessages);\r
+            return;\r
+        }\r
+\r
         if (prepared)\r
         {\r
             timeStamp.mHostTime = GetCurrentHostTime (numSamples, getSampleRate(), isAUv3);\r
@@ -1111,8 +1121,35 @@ public:
         }\r
     }\r
 \r
+    void processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages) override\r
+    {\r
+        processAudio (buffer, midiMessages, false);\r
+    }\r
+\r
+    void processBlockBypassed (AudioBuffer<float>& buffer, MidiBuffer& midiMessages) override\r
+    {\r
+        processAudio (buffer, midiMessages, true);\r
+    }\r
+\r
     //==============================================================================\r
-    bool hasEditor() const override                  { return true; }\r
+    AudioProcessorParameter* getBypassParameter() const override    { return auSupportsBypass ? bypassParam.get() : nullptr; }\r
+\r
+    bool hasEditor() const override\r
+    {\r
+       #if JUCE_MAC\r
+        return true;\r
+       #elif JUCE_SUPPORTS_AUv3\r
+        UInt32 dataSize;\r
+        Boolean isWritable;\r
+\r
+        return (AudioUnitGetPropertyInfo (audioUnit, kAudioUnitProperty_RequestViewController,\r
+                                          kAudioUnitScope_Global, 0, &dataSize, &isWritable) == noErr\r
+                && dataSize == sizeof (uintptr_t) && isWritable != 0);\r
+       #else\r
+        return false;\r
+       #endif\r
+    }\r
+\r
     AudioProcessorEditor* createEditor() override;\r
 \r
     static AudioProcessor::BusesProperties getBusesProperties (AudioComponentInstance comp)\r
@@ -1408,6 +1445,14 @@ public:
                 }\r
             }\r
         }\r
+\r
+        UInt32 propertySize = 0;\r
+        Boolean writable = false;\r
+\r
+        auSupportsBypass = (AudioUnitGetPropertyInfo (audioUnit, kAudioUnitProperty_BypassEffect,\r
+                                                     kAudioUnitScope_Global, 0, &propertySize, &writable) == noErr\r
+                              && propertySize >= sizeof (UInt32) && writable);\r
+        bypassParam = new AUBypassParameter (*this);\r
     }\r
 \r
     void updateLatency()\r
@@ -1439,7 +1484,7 @@ private:
     String pluginName, manufacturer, version;\r
     String fileOrIdentifier;\r
     CriticalSection lock;\r
-    bool wantsMidiMessages, producesMidiMessages, wasPlaying, prepared, isAUv3, isMidiEffectPlugin;\r
+    bool wantsMidiMessages, producesMidiMessages, wasPlaying, prepared, isAUv3, isMidiEffectPlugin, lastBypassValue = false;\r
 \r
     struct AUBuffer\r
     {\r
@@ -1459,6 +1504,99 @@ private:
         HeapBlock<AudioBufferList> bufferList;\r
     };\r
 \r
+    //==============================================================================\r
+    struct AUBypassParameter    : Parameter\r
+    {\r
+        AUBypassParameter (AudioUnitPluginInstance& effectToUse)\r
+             : parent (effectToUse), currentValue (getCurrentHostValue())\r
+        {}\r
+\r
+        bool getCurrentHostValue()\r
+        {\r
+            if (parent.auSupportsBypass)\r
+            {\r
+                UInt32 dataSize = sizeof (UInt32);\r
+                UInt32 value = 0;\r
+\r
+                if (AudioUnitGetProperty (parent.audioUnit, kAudioUnitProperty_BypassEffect,\r
+                                          kAudioUnitScope_Global, 0, &value, &dataSize) == noErr\r
+                               && dataSize == sizeof (UInt32))\r
+                    return (value != 0);\r
+            }\r
+\r
+            return false;\r
+        }\r
+\r
+        float getValue() const override\r
+        {\r
+            return currentValue ? 1.0f : 0.0f;\r
+        }\r
+\r
+        void setValue (float newValue) override\r
+        {\r
+            auto newBypassValue = (newValue != 0.0f);\r
+\r
+            const ScopedLock sl (parent.lock);\r
+\r
+            if (newBypassValue != currentValue)\r
+            {\r
+                currentValue = newBypassValue;\r
+\r
+                if (parent.auSupportsBypass)\r
+                {\r
+                    UInt32 value = (newValue != 0.0f ? 1 : 0);\r
+                    AudioUnitSetProperty (parent.audioUnit, kAudioUnitProperty_BypassEffect,\r
+                                          kAudioUnitScope_Global, 0, &value, sizeof (UInt32));\r
+\r
+                   #if JUCE_MAC\r
+                    jassert (parent.audioUnit != nullptr);\r
+\r
+                    AudioUnitEvent ev;\r
+                    ev.mEventType                       = kAudioUnitEvent_PropertyChange;\r
+                    ev.mArgument.mProperty.mAudioUnit   = parent.audioUnit;\r
+                    ev.mArgument.mProperty.mPropertyID  = kAudioUnitProperty_BypassEffect;\r
+                    ev.mArgument.mProperty.mScope       = kAudioUnitScope_Global;\r
+                    ev.mArgument.mProperty.mElement     = 0;\r
+\r
+                    AUEventListenerNotify (parent.eventListenerRef, nullptr, &ev);\r
+                   #endif\r
+                }\r
+            }\r
+        }\r
+\r
+        float getValueForText (const String& text) const override\r
+        {\r
+            String lowercaseText (text.toLowerCase());\r
+\r
+            for (auto& testText : onStrings)\r
+                if (lowercaseText == testText)\r
+                    return 1.0f;\r
+\r
+            for (auto& testText : offStrings)\r
+                if (lowercaseText == testText)\r
+                    return 0.0f;\r
+\r
+            return text.getIntValue() != 0 ? 1.0f : 0.0f;\r
+        }\r
+\r
+        float getDefaultValue() const override                              { return 0.0f; }\r
+        String getName (int /*maximumStringLength*/) const override         { return "Bypass"; }\r
+        String getText (float value, int) const override                    { return (value != 0.0f ? TRANS("On") : TRANS("Off")); }\r
+        bool isAutomatable() const override                                 { return true; }\r
+        bool isDiscrete() const override                                    { return true; }\r
+        bool isBoolean() const override                                     { return true; }\r
+        int getNumSteps() const override                                    { return 2; }\r
+        StringArray getAllValueStrings() const override                     { return values; }\r
+        String getLabel() const override                                    { return {}; }\r
+\r
+        AudioUnitPluginInstance& parent;\r
+        const StringArray onStrings  { TRANS("on"),  TRANS("yes"), TRANS("true") };\r
+        const StringArray offStrings { TRANS("off"), TRANS("no"),  TRANS("false") };\r
+        const StringArray values { TRANS("Off"), TRANS("On") };\r
+\r
+        bool currentValue = false;\r
+    };\r
+\r
     OwnedArray<AUBuffer> outputBufferList;\r
     AudioTimeStamp timeStamp;\r
     AudioBuffer<float>* currentBuffer;\r
@@ -1477,6 +1615,8 @@ private:
     MidiDataConcatenator midiConcatenator;\r
     CriticalSection midiInLock;\r
     MidiBuffer incomingMidi;\r
+    ScopedPointer<AUBypassParameter> bypassParam;\r
+    bool lastProcessBlockCallWasBypass = false, auSupportsBypass = false;\r
 \r
     void createPluginCallbacks()\r
     {\r
@@ -1536,6 +1676,7 @@ private:
             addPropertyChangeListener (kAudioUnitProperty_PresentPreset);\r
             addPropertyChangeListener (kAudioUnitProperty_ParameterList);\r
             addPropertyChangeListener (kAudioUnitProperty_Latency);\r
+            addPropertyChangeListener (kAudioUnitProperty_BypassEffect);\r
            #endif\r
         }\r
     }\r
@@ -1607,6 +1748,9 @@ private:
                     sendAllParametersChangedEvents();\r
                 else if (event.mArgument.mProperty.mPropertyID == kAudioUnitProperty_Latency)\r
                     updateLatency();\r
+                else if (event.mArgument.mProperty.mPropertyID == kAudioUnitProperty_BypassEffect)\r
+                    if (bypassParam != nullptr)\r
+                        bypassParam->setValueNotifyingHost (bypassParam->getValue());\r
 \r
                 break;\r
         }\r
@@ -2038,6 +2182,23 @@ private:
         return false;\r
     }\r
 \r
+    //==============================================================================\r
+    void updateBypass (bool processBlockBypassedCalled)\r
+    {\r
+        if (processBlockBypassedCalled && bypassParam != nullptr)\r
+        {\r
+            if (bypassParam->getValue() == 0.0f || ! lastProcessBlockCallWasBypass)\r
+                bypassParam->setValue (1.0f);\r
+        }\r
+        else\r
+        {\r
+            if (lastProcessBlockCallWasBypass && bypassParam != nullptr)\r
+                bypassParam->setValue (0.0f);\r
+        }\r
+\r
+        lastProcessBlockCallWasBypass = processBlockBypassedCalled;\r
+    }\r
+\r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioUnitPluginInstance)\r
 };\r
 \r
@@ -2169,9 +2330,7 @@ private:
        #if JUCE_SUPPORTS_AUv3\r
         if (AudioUnitGetPropertyInfo (plugin.audioUnit, kAudioUnitProperty_RequestViewController, kAudioUnitScope_Global,\r
                                           0, &dataSize, &isWritable) == noErr\r
-                && dataSize == sizeof (ViewControllerCallbackBlock)\r
-                && AudioUnitGetPropertyInfo (plugin.audioUnit, kAudioUnitProperty_RequestViewController, kAudioUnitScope_Global,\r
-                                             0, &dataSize, &isWritable) == noErr)\r
+                && dataSize == sizeof (ViewControllerCallbackBlock))\r
         {\r
             waitingForViewCallback = true;\r
             ViewControllerCallbackBlock callback;\r
@@ -2607,11 +2766,11 @@ StringArray AudioUnitPluginFormat::searchPathsForPlugins (const FileSearchPath&,
         {\r
             ignoreUnused (allowPluginsWhichRequireAsynchronousInstantiation);\r
 \r
-          #if JUCE_SUPPORTS_AUv3\r
+           #if JUCE_SUPPORTS_AUv3\r
             bool isAUv3 = ((desc.componentFlags & kAudioComponentFlag_IsV3AudioUnit) != 0);\r
 \r
             if (allowPluginsWhichRequireAsynchronousInstantiation || ! isAUv3)\r
-          #endif\r
+           #endif\r
                 result.add (AudioUnitFormatHelpers::createPluginIdentifier (desc));\r
         }\r
     }\r
diff --git a/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp b/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp
new file mode 100644 (file)
index 0000000..aa0c5d6
--- /dev/null
@@ -0,0 +1,185 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+namespace juce\r
+{\r
+\r
+#if JUCE_GCC\r
+ #pragma GCC diagnostic push\r
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"\r
+#elif JUCE_CLANG\r
+ #pragma clang diagnostic push\r
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"\r
+#elif JUCE_MSVC\r
+ #pragma warning (push, 0)\r
+ #pragma warning (disable: 4996)\r
+#endif\r
+\r
+class LegacyAudioParameter :   public AudioProcessorParameter\r
+{\r
+public:\r
+    LegacyAudioParameter (AudioProcessor& audioProcessorToUse, int audioParameterIndex)\r
+        : audioProcessor (audioProcessorToUse), idx (audioParameterIndex)\r
+    {\r
+        jassert (idx < audioProcessor.getNumParameters());\r
+    }\r
+\r
+    //==============================================================================\r
+    float getValue() const override                    { return audioProcessor.getParameter (idx); }\r
+    void setValue (float newValue) override            { audioProcessor.setParameter (idx, newValue); }\r
+    float getDefaultValue() const override             { return audioProcessor.getParameterDefaultValue (idx); }\r
+    String getName (int maxLen) const override         { return audioProcessor.getParameterName (idx, maxLen); }\r
+    String getLabel() const override                   { return audioProcessor.getParameterLabel (idx); }\r
+    int getNumSteps() const override                   { return audioProcessor.getParameterNumSteps (idx); }\r
+    bool isDiscrete() const override                   { return audioProcessor.isParameterDiscrete (idx); }\r
+    bool isBoolean() const override                    { return false; }\r
+    bool isOrientationInverted() const override        { return audioProcessor.isParameterOrientationInverted (idx); }\r
+    bool isAutomatable() const override                { return audioProcessor.isParameterAutomatable (idx); }\r
+    bool isMetaParameter() const override              { return audioProcessor.isMetaParameter (idx); }\r
+    Category getCategory() const override              { return audioProcessor.getParameterCategory (idx); }\r
+    String getCurrentValueAsText() const override      { return audioProcessor.getParameterText (idx); }\r
+    String getParamID() const                          { return audioProcessor.getParameterID (idx); }\r
+\r
+    //==============================================================================\r
+    float getValueForText (const String&) const override\r
+    {\r
+        // legacy parameters do not support this method\r
+        jassertfalse;\r
+        return 0.0f;\r
+    }\r
+\r
+    String getText (float, int) const override\r
+    {\r
+        // legacy parameters do not support this method\r
+        jassertfalse;\r
+        return {};\r
+    }\r
+\r
+    //==============================================================================\r
+    static bool isLegacy (AudioProcessorParameter* param) noexcept\r
+    {\r
+        return (dynamic_cast<LegacyAudioParameter*> (param) != nullptr);\r
+    }\r
+\r
+    static int getParamIndex (AudioProcessor& processor, AudioProcessorParameter* param) noexcept\r
+    {\r
+        if (auto* legacy = dynamic_cast<LegacyAudioParameter*> (param))\r
+        {\r
+            return legacy->idx;\r
+        }\r
+        else\r
+        {\r
+            auto n = processor.getNumParameters();\r
+            jassert (n == processor.getParameters().size());\r
+\r
+            for (int i = 0; i < n; ++i)\r
+            {\r
+                if (processor.getParameters()[i] == param)\r
+                    return i;\r
+            }\r
+        }\r
+\r
+        return -1;\r
+    }\r
+\r
+    static String getParamID (AudioProcessorParameter* param, bool forceLegacyParamIDs) noexcept\r
+    {\r
+        if (auto* legacy = dynamic_cast<LegacyAudioParameter*> (param))\r
+        {\r
+            return legacy->getParamID();\r
+        }\r
+        else if (auto* paramWithID = dynamic_cast<AudioProcessorParameterWithID*> (param))\r
+        {\r
+            if (! forceLegacyParamIDs)\r
+                return paramWithID->paramID;\r
+        }\r
+\r
+        return String (param->getParameterIndex());\r
+    }\r
+private:\r
+    AudioProcessor& audioProcessor;\r
+    int idx;\r
+};\r
+\r
+//==============================================================================\r
+class LegacyAudioParametersWrapper\r
+{\r
+public:\r
+    void update (AudioProcessor& audioProcessor, bool forceLegacyParamIDs)\r
+    {\r
+        clear();\r
+\r
+        legacyParamIDs = forceLegacyParamIDs;\r
+\r
+        auto numParameters = audioProcessor.getNumParameters();\r
+        usingManagedParameters = (audioProcessor.getParameters().size() == numParameters) && (! legacyParamIDs);\r
+\r
+        for (int i = 0; i < numParameters; ++i)\r
+        {\r
+            AudioProcessorParameter* param = usingManagedParameters ? audioProcessor.getParameters()[i]\r
+                                                                    : (legacy.add (new LegacyAudioParameter (audioProcessor, i)));\r
+            params.add (param);\r
+        }\r
+    }\r
+\r
+    void clear()\r
+    {\r
+        legacy.clear();\r
+        params.clear();\r
+    }\r
+\r
+    AudioProcessorParameter* getParamForIndex (int index) const\r
+    {\r
+        if (isPositiveAndBelow (index, params.size()))\r
+            return params[index];\r
+\r
+        return nullptr;\r
+    }\r
+\r
+    String getParamID (AudioProcessor& processor, int idx) const noexcept\r
+    {\r
+        return usingManagedParameters ? processor.getParameterID (idx) : String (idx);\r
+    }\r
+\r
+    bool isUsingManagedParameters() const noexcept    { return usingManagedParameters; }\r
+    int getNumParameters() const noexcept             { return params.size(); }\r
+\r
+    Array<AudioProcessorParameter*> params;\r
+\r
+private:\r
+    OwnedArray<LegacyAudioParameter> legacy;\r
+    bool legacyParamIDs = false, usingManagedParameters = false;\r
+};\r
+\r
+#if JUCE_GCC\r
+ #pragma GCC diagnostic pop\r
+#elif JUCE_CLANG\r
+ #pragma clang diagnostic pop\r
+#elif JUCE_MSVC\r
+ #pragma warning (pop)\r
+#endif\r
+\r
+} // namespace juce\r
index bf68a9e7cfd7b7ce6b323f27c6fa76a0c1fd2cee..466478d62a357097c31ad9a064f6206c8b76b7d7 100644 (file)
@@ -1883,14 +1883,18 @@ struct VST3PluginInstance : public AudioPluginInstance
             int numSteps = isDiscrete ? paramInfo.stepCount + 1\r
                                       : AudioProcessor::getDefaultNumParameterSteps();\r
 \r
-            addParameter (new VST3Parameter (*this,\r
-                                             paramInfo.id,\r
-                                             toString (paramInfo.title),\r
-                                             toString (paramInfo.units),\r
-                                             paramInfo.defaultNormalizedValue,\r
-                                             (paramInfo.flags & Vst::ParameterInfo::kCanAutomate) != 0,\r
-                                             isDiscrete,\r
-                                             numSteps));\r
+            VST3Parameter* p = new VST3Parameter (*this,\r
+                                                  paramInfo.id,\r
+                                                  toString (paramInfo.title),\r
+                                                  toString (paramInfo.units),\r
+                                                  paramInfo.defaultNormalizedValue,\r
+                                                  (paramInfo.flags & Vst::ParameterInfo::kCanAutomate) != 0,\r
+                                                  isDiscrete,\r
+                                                  numSteps);\r
+            addParameter (p);\r
+\r
+            if ((paramInfo.flags & Vst::ParameterInfo::kIsBypass) != 0)\r
+                bypassParam = p;\r
         }\r
 \r
         synchroniseStates();\r
@@ -2015,12 +2019,13 @@ struct VST3PluginInstance : public AudioPluginInstance
         return (processor->canProcessSampleSize (Vst::kSample64) == kResultTrue);\r
     }\r
 \r
+    //==============================================================================\r
     void processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages) override\r
     {\r
         jassert (! isUsingDoublePrecision());\r
 \r
         if (isActive && processor != nullptr)\r
-            processAudio (buffer, midiMessages, Vst::kSample32);\r
+            processAudio (buffer, midiMessages, Vst::kSample32, false);\r
     }\r
 \r
     void processBlock (AudioBuffer<double>& buffer, MidiBuffer& midiMessages) override\r
@@ -2028,12 +2033,43 @@ struct VST3PluginInstance : public AudioPluginInstance
         jassert (isUsingDoublePrecision());\r
 \r
         if (isActive && processor != nullptr)\r
-            processAudio (buffer, midiMessages, Vst::kSample64);\r
+            processAudio (buffer, midiMessages, Vst::kSample64, false);\r
+    }\r
+\r
+    void processBlockBypassed (AudioBuffer<float>& buffer, MidiBuffer& midiMessages) override\r
+    {\r
+        jassert (! isUsingDoublePrecision());\r
+\r
+        if (bypassParam != nullptr)\r
+        {\r
+            if (isActive && processor != nullptr)\r
+                processAudio (buffer, midiMessages, Vst::kSample32, true);\r
+        }\r
+        else\r
+        {\r
+            AudioProcessor::processBlockBypassed (buffer, midiMessages);\r
+        }\r
+    }\r
+\r
+    void processBlockBypassed (AudioBuffer<double>& buffer, MidiBuffer& midiMessages) override\r
+    {\r
+        jassert (isUsingDoublePrecision());\r
+\r
+        if (bypassParam != nullptr)\r
+        {\r
+            if (isActive && processor != nullptr)\r
+                processAudio (buffer, midiMessages, Vst::kSample64, true);\r
+        }\r
+        else\r
+        {\r
+            AudioProcessor::processBlockBypassed (buffer, midiMessages);\r
+        }\r
     }\r
 \r
+    //==============================================================================\r
     template <typename FloatType>\r
     void processAudio (AudioBuffer<FloatType>& buffer, MidiBuffer& midiMessages,\r
-                       Vst::SymbolicSampleSizes sampleSize)\r
+                       Vst::SymbolicSampleSizes sampleSize, bool isProcessBlockBypassedCall)\r
     {\r
         using namespace Vst;\r
         auto numSamples = buffer.getNumSamples();\r
@@ -2041,6 +2077,8 @@ struct VST3PluginInstance : public AudioPluginInstance
         auto numInputAudioBuses  = getBusCount (true);\r
         auto numOutputAudioBuses = getBusCount (false);\r
 \r
+        updateBypass (isProcessBlockBypassedCall);\r
+\r
         ProcessData data;\r
         data.processMode            = isNonRealtime() ? kOffline : kRealtime;\r
         data.symbolicSampleSize     = sampleSize;\r
@@ -2266,6 +2304,9 @@ struct VST3PluginInstance : public AudioPluginInstance
     bool acceptsMidi() const override    { return getNumSingleDirectionBusesFor (holder->component, true,  false) > 0; }\r
     bool producesMidi() const override   { return getNumSingleDirectionBusesFor (holder->component, false, false) > 0; }\r
 \r
+    //==============================================================================\r
+    AudioProcessorParameter* getBypassParameter() const override         { return bypassParam; }\r
+\r
     //==============================================================================\r
     /** May return a negative value as a means of informing us that the plugin has "infinite tail," or 0 for "no tail." */\r
     double getTailLengthSeconds() const override\r
@@ -2588,7 +2629,8 @@ private:
     ComSmartPtr<ParamValueQueueList> inputParameterChanges, outputParameterChanges;\r
     ComSmartPtr<MidiEventList> midiInputs, midiOutputs;\r
     Vst::ProcessContext timingInfo; //< Only use this in processBlock()!\r
-    bool isControllerInitialised = false, isActive = false;\r
+    bool isControllerInitialised = false, isActive = false, lastProcessBlockCallWasBypass = false;\r
+    VST3Parameter* bypassParam = nullptr;\r
 \r
     //==============================================================================\r
     /** Some plugins need to be "connected" to intercommunicate between their implemented classes */\r
@@ -2705,6 +2747,28 @@ private:
         return busInfo;\r
     }\r
 \r
+    //==============================================================================\r
+    void updateBypass (bool processBlockBypassedCalled)\r
+    {\r
+        // to remain backward compatible, the logic needs to be the following:\r
+        // - if processBlockBypassed was called then definitely bypass the VST3\r
+        // - if processBlock was called then only un-bypass the VST3 if the previous\r
+        //   call was processBlockBypassed, otherwise do nothing\r
+        if (processBlockBypassedCalled)\r
+        {\r
+            if (bypassParam != nullptr && (bypassParam->getValue() == 0.0f || ! lastProcessBlockCallWasBypass))\r
+                bypassParam->setValue (1.0f);\r
+        }\r
+        else\r
+        {\r
+            if (lastProcessBlockCallWasBypass && bypassParam != nullptr)\r
+                bypassParam->setValue (0.0f);\r
+\r
+        }\r
+\r
+        lastProcessBlockCallWasBypass = processBlockBypassedCalled;\r
+    }\r
+\r
     //==============================================================================\r
     /** @note An IPlugView, when first created, should start with a ref-count of 1! */\r
     IPlugView* tryCreatingView() const\r
index 8b19413b8297e3b1c6b60dff1b10d92dd9f2fc69..c3c5e31511433c624811087fb055db6ff208f96a 100644 (file)
@@ -979,7 +979,8 @@ struct VSTPluginInstance     : public AudioPluginInstance,
         : AudioPluginInstance (ioConfig),\r
           vstEffect (effect),\r
           vstModule (mh),\r
-          name (mh->pluginName)\r
+          name (mh->pluginName),\r
+          bypassParam (new VST2BypassParameter (*this))\r
     {\r
         jassert (vstEffect != nullptr);\r
 \r
@@ -1063,6 +1064,7 @@ struct VSTPluginInstance     : public AudioPluginInstance,
                                             valueType));\r
         }\r
 \r
+        vstSupportsBypass = pluginCanDo ("bypass");\r
         setRateAndBufferSizeDetails (sampleRateToUse, blockSizeToUse);\r
     }\r
 \r
@@ -1399,24 +1401,40 @@ struct VSTPluginInstance     : public AudioPluginInstance,
         }\r
     }\r
 \r
+    //==============================================================================\r
     void processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages) override\r
     {\r
         jassert (! isUsingDoublePrecision());\r
-        processAudio (buffer, midiMessages, tmpBufferFloat, channelBufferFloat);\r
+        processAudio (buffer, midiMessages, tmpBufferFloat, channelBufferFloat, false);\r
     }\r
 \r
     void processBlock (AudioBuffer<double>& buffer, MidiBuffer& midiMessages) override\r
     {\r
         jassert (isUsingDoublePrecision());\r
-        processAudio (buffer, midiMessages, tmpBufferDouble, channelBufferDouble);\r
+        processAudio (buffer, midiMessages, tmpBufferDouble, channelBufferDouble, false);\r
+    }\r
+\r
+    void processBlockBypassed (AudioBuffer<float>& buffer, MidiBuffer& midiMessages) override\r
+    {\r
+        jassert (! isUsingDoublePrecision());\r
+        processAudio (buffer, midiMessages, tmpBufferFloat, channelBufferFloat, true);\r
+    }\r
+\r
+    void processBlockBypassed (AudioBuffer<double>& buffer, MidiBuffer& midiMessages) override\r
+    {\r
+        jassert (isUsingDoublePrecision());\r
+        processAudio (buffer, midiMessages, tmpBufferDouble, channelBufferDouble, true);\r
     }\r
 \r
+    //==============================================================================\r
     bool supportsDoublePrecisionProcessing() const override\r
     {\r
         return ((vstEffect->flags & vstEffectFlagInplaceAudio) != 0\r
              && (vstEffect->flags & vstEffectFlagInplaceDoubleAudio) != 0);\r
     }\r
 \r
+    AudioProcessorParameter* getBypassParameter() const override               { return vstSupportsBypass ? bypassParam.get() : nullptr; }\r
+\r
     //==============================================================================\r
     bool canAddBus (bool) const override                                       { return false; }\r
     bool canRemoveBus (bool) const override                                    { return false; }\r
@@ -1932,9 +1950,57 @@ struct VSTPluginInstance     : public AudioPluginInstance,
     bool usesCocoaNSView = false;\r
 \r
 private:\r
+    //==============================================================================\r
+    struct VST2BypassParameter    : Parameter\r
+    {\r
+        VST2BypassParameter (VSTPluginInstance& effectToUse)   : parent (effectToUse) {}\r
+\r
+        void setValue (float newValue) override\r
+        {\r
+            currentValue = (newValue != 0.0f);\r
+\r
+            if (parent.vstSupportsBypass)\r
+                parent.dispatch (plugInOpcodeSetBypass, 0, currentValue ? 1 : 0, nullptr, 0.0f);\r
+        }\r
+\r
+        float getValueForText (const String& text) const override\r
+        {\r
+            String lowercaseText (text.toLowerCase());\r
+\r
+            for (auto& testText : onStrings)\r
+                if (lowercaseText == testText)\r
+                    return 1.0f;\r
+\r
+            for (auto& testText : offStrings)\r
+                if (lowercaseText == testText)\r
+                    return 0.0f;\r
+\r
+            return text.getIntValue() != 0 ? 1.0f : 0.0f;\r
+        }\r
+\r
+        float getValue() const override                                     { return currentValue; }\r
+        float getDefaultValue() const override                              { return 0.0f; }\r
+        String getName (int /*maximumStringLength*/) const override         { return "Bypass"; }\r
+        String getText (float value, int) const override                    { return (value != 0.0f ? TRANS("On") : TRANS("Off")); }\r
+        bool isAutomatable() const override                                 { return true; }\r
+        bool isDiscrete() const override                                    { return true; }\r
+        bool isBoolean() const override                                     { return true; }\r
+        int getNumSteps() const override                                    { return 2; }\r
+        StringArray getAllValueStrings() const override                     { return values; }\r
+        String getLabel() const override                                    { return {}; }\r
+\r
+        VSTPluginInstance& parent;\r
+        bool currentValue = false;\r
+        StringArray onStrings  { TRANS("on"),  TRANS("yes"), TRANS("true") };\r
+        StringArray offStrings { TRANS("off"), TRANS("no"),  TRANS("false") };\r
+        StringArray values { TRANS("Off"), TRANS("On") };\r
+    };\r
+\r
+    //==============================================================================\r
     String name;\r
     CriticalSection lock;\r
     bool wantsMidiMessages = false, initialised = false, isPowerOn = false;\r
+    bool lastProcessBlockCallWasBypass = false, vstSupportsBypass = false;\r
     mutable StringArray programNames;\r
     AudioBuffer<float> outOfPlaceBuffer;\r
 \r
@@ -1948,6 +2014,7 @@ private:
 \r
     AudioBuffer<double> tmpBufferDouble;\r
     HeapBlock<double*> channelBufferDouble;\r
+    ScopedPointer<VST2BypassParameter> bypassParam;\r
 \r
     ScopedPointer<VSTXMLInfo> xmlInfo;\r
 \r
@@ -2202,8 +2269,20 @@ private:
     template <typename FloatType>\r
     void processAudio (AudioBuffer<FloatType>& buffer, MidiBuffer& midiMessages,\r
                        AudioBuffer<FloatType>& tmpBuffer,\r
-                       HeapBlock<FloatType*>& channelBuffer)\r
+                       HeapBlock<FloatType*>& channelBuffer,\r
+                       bool processBlockBypassedCalled)\r
     {\r
+        if (vstSupportsBypass)\r
+        {\r
+            updateBypass (processBlockBypassedCalled);\r
+        }\r
+        else if (processBlockBypassedCalled)\r
+        {\r
+            // if this vst does not support bypass then we will have to do this ourselves\r
+            AudioProcessor::processBlockBypassed (buffer, midiMessages);\r
+            return;\r
+        }\r
+\r
         auto numSamples  = buffer.getNumSamples();\r
         auto numChannels = buffer.getNumChannels();\r
 \r
@@ -2588,6 +2667,23 @@ private:
         isPowerOn = on;\r
     }\r
 \r
+    //==============================================================================\r
+    void updateBypass (bool processBlockBypassedCalled)\r
+    {\r
+        if (processBlockBypassedCalled)\r
+        {\r
+            if (bypassParam->getValue() == 0.0f || ! lastProcessBlockCallWasBypass)\r
+                bypassParam->setValue (1.0f);\r
+        }\r
+        else\r
+        {\r
+            if (lastProcessBlockCallWasBypass)\r
+                bypassParam->setValue (0.0f);\r
+        }\r
+\r
+        lastProcessBlockCallWasBypass = processBlockBypassedCalled;\r
+    }\r
+\r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginInstance)\r
 };\r
 \r
index c5ef4a0b58bbda57077a6e02547429ec1b8018dd..ed56fdb87da0e175967ff96d20e510464893d713 100644 (file)
@@ -154,6 +154,7 @@ struct AutoResizingNSViewComponentWithParent  : public AutoResizingNSViewCompone
 \r
 #include "format/juce_AudioPluginFormat.cpp"\r
 #include "format/juce_AudioPluginFormatManager.cpp"\r
+#include "format_types/juce_LegacyAudioParameter.cpp"\r
 #include "processors/juce_AudioProcessor.cpp"\r
 #include "processors/juce_AudioPluginInstance.cpp"\r
 #include "processors/juce_AudioProcessorEditor.cpp"\r
index 406557d152cade9b3af434bbb6161e8acafc93fb..a5fcee522365b2296f64604519ab97836f6565a2 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_audio_processors\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE audio processor classes\r
   description:      Classes for loading and playing VST, AU, or internally-generated audio processors.\r
   website:          http://www.juce.com/juce\r
index 5888a6102dd05a204101e48eea9f592c821ddb09..6190aa2557b3f1853f9250f2a88f19f724f2d6c4 100644 (file)
 namespace juce\r
 {\r
 \r
+#if JUCE_MSVC\r
+ #pragma warning (push, 0)\r
+\r
+ // MSVC does not like it if you override a deprecated method even if you\r
+ // keep the deprecation attribute. Other compilers are more forgiving.\r
+ #pragma warning (disable: 4996)\r
+#endif\r
+\r
 //==============================================================================\r
 /**\r
     Base class for an active instance of a plugin.\r
@@ -123,4 +131,8 @@ private:
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginInstance)\r
 };\r
 \r
+#if JUCE_MSVC\r
+ #pragma warning (pop)\r
+#endif\r
+\r
 } // namespace juce\r
index 5e389ee10b89f8296f5b6f29ea903615d60f5bb4..43658a5772be1c6444835975c82f7adaefe9d524 100644 (file)
@@ -414,6 +414,18 @@ void AudioProcessor::setLatencySamples (const int newLatency)
     }\r
 }\r
 \r
+//==============================================================================\r
+#if JUCE_GCC\r
+ #pragma GCC diagnostic push\r
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"\r
+#elif JUCE_CLANG\r
+ #pragma clang diagnostic push\r
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"\r
+#elif JUCE_MSVC\r
+ #pragma warning (push, 0)\r
+ #pragma warning (disable: 4996)\r
+#endif\r
+\r
 void AudioProcessor::setParameterNotifyingHost (int parameterIndex, float newValue)\r
 {\r
     if (auto* param = getParameters()[parameterIndex])\r
@@ -427,12 +439,6 @@ void AudioProcessor::setParameterNotifyingHost (int parameterIndex, float newVal
     }\r
 }\r
 \r
-AudioProcessorListener* AudioProcessor::getListenerLocked (int index) const noexcept\r
-{\r
-    const ScopedLock sl (listenerLock);\r
-    return listeners[index];\r
-}\r
-\r
 void AudioProcessor::sendParamChangeMessageToListeners (int parameterIndex, float newValue)\r
 {\r
     if (auto* param = getParameters()[parameterIndex])\r
@@ -511,6 +517,49 @@ void AudioProcessor::endParameterChangeGesture (int parameterIndex)
     }\r
 }\r
 \r
+String AudioProcessor::getParameterName (int index, int maximumStringLength)\r
+{\r
+    if (auto* p = managedParameters[index])\r
+        return p->getName (maximumStringLength);\r
+\r
+    return getParameterName (index).substring (0, maximumStringLength);\r
+}\r
+\r
+const String AudioProcessor::getParameterText (int index)\r
+{\r
+   #if JUCE_DEBUG\r
+    // if you hit this, then you're probably using the old parameter control methods,\r
+    // but have forgotten to implement either of the getParameterText() methods.\r
+    jassert (! textRecursionCheck);\r
+    ScopedValueSetter<bool> sv (textRecursionCheck, true, false);\r
+   #endif\r
+\r
+    return getParameterText (index, 1024);\r
+}\r
+\r
+String AudioProcessor::getParameterText (int index, int maximumStringLength)\r
+{\r
+    if (auto* p = managedParameters[index])\r
+        return p->getText (p->getValue(), maximumStringLength);\r
+\r
+    return getParameterText (index).substring (0, maximumStringLength);\r
+}\r
+\r
+#if JUCE_GCC\r
+ #pragma GCC diagnostic pop\r
+#elif JUCE_CLANG\r
+ #pragma clang diagnostic pop\r
+#elif JUCE_MSVC\r
+ #pragma warning (pop)\r
+#endif\r
+\r
+//==============================================================================\r
+AudioProcessorListener* AudioProcessor::getListenerLocked (int index) const noexcept\r
+{\r
+    const ScopedLock sl (listenerLock);\r
+    return listeners[index];\r
+}\r
+\r
 void AudioProcessor::updateHostDisplay()\r
 {\r
     for (int i = listeners.size(); --i >= 0;)\r
@@ -567,34 +616,6 @@ String AudioProcessor::getParameterID (int index)
     return String (index);\r
 }\r
 \r
-String AudioProcessor::getParameterName (int index, int maximumStringLength)\r
-{\r
-    if (auto* p = managedParameters[index])\r
-        return p->getName (maximumStringLength);\r
-\r
-    return getParameterName (index).substring (0, maximumStringLength);\r
-}\r
-\r
-const String AudioProcessor::getParameterText (int index)\r
-{\r
-   #if JUCE_DEBUG\r
-    // if you hit this, then you're probably using the old parameter control methods,\r
-    // but have forgotten to implement either of the getParameterText() methods.\r
-    jassert (! textRecursionCheck);\r
-    ScopedValueSetter<bool> sv (textRecursionCheck, true, false);\r
-   #endif\r
-\r
-    return getParameterText (index, 1024);\r
-}\r
-\r
-String AudioProcessor::getParameterText (int index, int maximumStringLength)\r
-{\r
-    if (auto* p = managedParameters[index])\r
-        return p->getText (p->getValue(), maximumStringLength);\r
-\r
-    return getParameterText (index).substring (0, maximumStringLength);\r
-}\r
-\r
 int AudioProcessor::getParameterNumSteps (int index)\r
 {\r
     if (auto* p = managedParameters[index])\r
@@ -1368,9 +1389,6 @@ AudioProcessorParameter::~AudioProcessorParameter()
 \r
 void AudioProcessorParameter::setValueNotifyingHost (float newValue)\r
 {\r
-    // This method can't be used until the parameter has been attached to a processor!\r
-    jassert (processor != nullptr && parameterIndex >= 0);\r
-\r
     setValue (newValue);\r
     sendValueChangedMessageToListeners (newValue);\r
 }\r
@@ -1394,11 +1412,14 @@ void AudioProcessorParameter::beginChangeGesture()
         if (auto* l = listeners[i])\r
             l->parameterGestureChanged (getParameterIndex(), true);\r
 \r
-    // audioProcessorParameterChangeGestureBegin callbacks will shortly be deprecated and\r
-    // this code will be removed.\r
-    for (int i = processor->listeners.size(); --i >= 0;)\r
-        if (auto* l = processor->listeners[i])\r
-            l->audioProcessorParameterChangeGestureBegin (processor, getParameterIndex());\r
+    if (processor != nullptr && parameterIndex >= 0)\r
+    {\r
+        // audioProcessorParameterChangeGestureBegin callbacks will shortly be deprecated and\r
+        // this code will be removed.\r
+        for (int i = processor->listeners.size(); --i >= 0;)\r
+            if (auto* l = processor->listeners[i])\r
+                l->audioProcessorParameterChangeGestureBegin (processor, getParameterIndex());\r
+    }\r
 }\r
 \r
 void AudioProcessorParameter::endChangeGesture()\r
@@ -1420,11 +1441,14 @@ void AudioProcessorParameter::endChangeGesture()
         if (auto* l = listeners[i])\r
             l->parameterGestureChanged (getParameterIndex(), false);\r
 \r
-    // audioProcessorParameterChangeGestureEnd callbacks will shortly be deprecated and\r
-    // this code will be removed.\r
-    for (int i = processor->listeners.size(); --i >= 0;)\r
-        if (auto* l = processor->listeners[i])\r
-            l->audioProcessorParameterChangeGestureEnd (processor, getParameterIndex());\r
+    if (processor != nullptr && parameterIndex >= 0)\r
+    {\r
+        // audioProcessorParameterChangeGestureEnd callbacks will shortly be deprecated and\r
+        // this code will be removed.\r
+        for (int i = processor->listeners.size(); --i >= 0;)\r
+            if (auto* l = processor->listeners[i])\r
+                l->audioProcessorParameterChangeGestureEnd (processor, getParameterIndex());\r
+    }\r
 }\r
 \r
 void AudioProcessorParameter::sendValueChangedMessageToListeners (float newValue)\r
@@ -1435,11 +1459,14 @@ void AudioProcessorParameter::sendValueChangedMessageToListeners (float newValue
         if (auto* l = listeners [i])\r
             l->parameterValueChanged (getParameterIndex(), newValue);\r
 \r
-    // audioProcessorParameterChanged callbacks will shortly be deprecated and\r
-    // this code will be removed.\r
-    for (int i = processor->listeners.size(); --i >= 0;)\r
-        if (auto* l = processor->listeners[i])\r
-            l->audioProcessorParameterChanged (processor, getParameterIndex(), newValue);\r
+    if (processor != nullptr && parameterIndex >= 0)\r
+    {\r
+        // audioProcessorParameterChanged callbacks will shortly be deprecated and\r
+        // this code will be removed.\r
+        for (int i = processor->listeners.size(); --i >= 0;)\r
+            if (auto* l = processor->listeners[i])\r
+                l->audioProcessorParameterChanged (processor, getParameterIndex(), newValue);\r
+    }\r
 }\r
 \r
 bool AudioProcessorParameter::isOrientationInverted() const                      { return false; }\r
index c2c2cb633ff252b09605997af6cf46ff7338b429..11122fc04868a5a189ba7d0d643b9b7a576ca63a 100644 (file)
@@ -188,6 +188,13 @@ public:
         be the processor's MIDI output. This means that your processor should be careful to\r
         clear any incoming messages from the array if it doesn't want them to be passed-on.\r
 \r
+        If you have implemented the getBypassParameter method, then you need to check the\r
+        value of this parameter in this callback and bypass your processing if the parameter\r
+        has a non-zero value.\r
+\r
+        Note that when calling this method as a host, the result may still be bypassed as\r
+        the parameter that controls the bypass may be non-zero.\r
+\r
         Be very careful about what you do in this callback - it's going to be called by\r
         the audio thread, so any kind of interaction with the UI is absolutely\r
         out of the question. If you change a parameter in here and need to tell your UI to\r
@@ -252,6 +259,13 @@ public:
         be the processor's MIDI output. This means that your processor should be careful to\r
         clear any incoming messages from the array if it doesn't want them to be passed-on.\r
 \r
+        If you have implemented the getBypassParameter method, then you need to check the\r
+        value of this parameter in this callback and bypass your processing if the parameter\r
+        has a non-zero value.\r
+\r
+        Note that when calling this method as a host, the result may still be bypassed as\r
+        the parameter that controls the bypass may be non-zero.\r
+\r
         Be very careful about what you do in this callback - it's going to be called by\r
         the audio thread, so any kind of interaction with the UI is absolutely\r
         out of the question. If you change a parameter in here and need to tell your UI to\r
@@ -890,6 +904,21 @@ public:
     */\r
     virtual void reset();\r
 \r
+    //==============================================================================\r
+    /** Returns the parameter that controls the AudioProcessor's bypass state.\r
+\r
+        If this method returns a nullptr then you can still control the bypass by\r
+        calling processBlockBypassed instaed of processBlock. On the other hand,\r
+        if this method returns a non-null value, you should never call\r
+        processBlockBypassed but use the returned parameter to conrol the bypass\r
+        state instead.\r
+\r
+        A plug-in can override this function to return a parameter which control's your\r
+        plug-in's bypass. You should always check the value of this parameter in your\r
+        processBlock callback and bypass any effects if it is non-zero.\r
+    */\r
+    virtual AudioProcessorParameter* getBypassParameter() const        { return nullptr; }\r
+\r
     //==============================================================================\r
     /** Returns true if the processor is being run in an offline mode for rendering.\r
 \r
@@ -962,14 +991,14 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use the\r
         AudioProcessorParameter class instead to manage your parameters.\r
     */\r
-    virtual int getNumParameters();\r
+    JUCE_DEPRECATED (virtual int getNumParameters());\r
 \r
     /** Returns the name of a particular parameter.\r
 \r
         NOTE! This method will eventually be deprecated! It's recommended that you use the\r
         AudioProcessorParameter class instead to manage your parameters.\r
     */\r
-    virtual const String getParameterName (int parameterIndex);\r
+    JUCE_DEPRECATED (virtual const String getParameterName (int parameterIndex));\r
 \r
     /** Returns the ID of a particular parameter.\r
 \r
@@ -980,7 +1009,7 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use the\r
         AudioProcessorParameterWithID class instead to manage your parameters.\r
      */\r
-    virtual String getParameterID (int index);\r
+    JUCE_DEPRECATED (virtual String getParameterID (int index));\r
 \r
     /** Called by the host to find out the value of one of the processor's parameters.\r
 \r
@@ -993,7 +1022,7 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use the\r
         AudioProcessorParameter class instead to manage your parameters.\r
     */\r
-    virtual float getParameter (int parameterIndex);\r
+    JUCE_DEPRECATED (virtual float getParameter (int parameterIndex));\r
 \r
     /** Returns the name of a parameter as a text string with a preferred maximum length.\r
         If you want to provide customised short versions of your parameter names that\r
@@ -1005,13 +1034,13 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use\r
         AudioProcessorParameter::getName() instead.\r
     */\r
-    virtual String getParameterName (int parameterIndex, int maximumStringLength);\r
+    JUCE_DEPRECATED (virtual String getParameterName (int parameterIndex, int maximumStringLength));\r
 \r
     /** Returns the value of a parameter as a text string.\r
         NOTE! This method will eventually be deprecated! It's recommended that you use\r
         AudioProcessorParameter::getText() instead.\r
     */\r
-    virtual const String getParameterText (int parameterIndex);\r
+    JUCE_DEPRECATED (virtual const String getParameterText (int parameterIndex));\r
 \r
     /** Returns the value of a parameter as a text string with a preferred maximum length.\r
         If you want to provide customised short versions of your parameter values that\r
@@ -1023,7 +1052,7 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use\r
         AudioProcessorParameter::getText() instead.\r
     */\r
-    virtual String getParameterText (int parameterIndex, int maximumStringLength);\r
+    JUCE_DEPRECATED (virtual String getParameterText (int parameterIndex, int maximumStringLength));\r
 \r
     /** Returns the number of discrete steps that this parameter can represent.\r
 \r
@@ -1043,7 +1072,7 @@ public:
 \r
         @see isParameterDiscrete\r
     */\r
-    virtual int getParameterNumSteps (int parameterIndex);\r
+    JUCE_DEPRECATED (virtual int getParameterNumSteps (int parameterIndex));\r
 \r
     /** Returns the default number of steps for a parameter.\r
 \r
@@ -1067,7 +1096,7 @@ public:
 \r
         @see getParameterNumSteps\r
     */\r
-    virtual bool isParameterDiscrete (int parameterIndex) const;\r
+    JUCE_DEPRECATED (virtual bool isParameterDiscrete (int parameterIndex) const);\r
 \r
     /** Returns the default value for the parameter.\r
         By default, this just returns 0.\r
@@ -1076,7 +1105,7 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use\r
         AudioProcessorParameter::getDefaultValue() instead.\r
     */\r
-    virtual float getParameterDefaultValue (int parameterIndex);\r
+    JUCE_DEPRECATED (virtual float getParameterDefaultValue (int parameterIndex));\r
 \r
     /** Some plugin types may be able to return a label string for a\r
         parameter's units.\r
@@ -1084,7 +1113,7 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use\r
         AudioProcessorParameter::getLabel() instead.\r
     */\r
-    virtual String getParameterLabel (int index) const;\r
+    JUCE_DEPRECATED (virtual String getParameterLabel (int index) const);\r
 \r
     /** This can be overridden to tell the host that particular parameters operate in the\r
         reverse direction. (Not all plugin formats or hosts will actually use this information).\r
@@ -1092,7 +1121,7 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use\r
         AudioProcessorParameter::isOrientationInverted() instead.\r
     */\r
-    virtual bool isParameterOrientationInverted (int index) const;\r
+    JUCE_DEPRECATED (virtual bool isParameterOrientationInverted (int index) const);\r
 \r
     /** The host will call this method to change the value of one of the processor's parameters.\r
 \r
@@ -1110,7 +1139,7 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use\r
         AudioProcessorParameter::setValue() instead.\r
     */\r
-    virtual void setParameter (int parameterIndex, float newValue);\r
+    JUCE_DEPRECATED (virtual void setParameter (int parameterIndex, float newValue));\r
 \r
     /** Your processor can call this when it needs to change one of its parameters.\r
 \r
@@ -1133,7 +1162,7 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use\r
         AudioProcessorParameter::isAutomatable() instead.\r
     */\r
-    virtual bool isParameterAutomatable (int parameterIndex) const;\r
+    JUCE_DEPRECATED (virtual bool isParameterAutomatable (int parameterIndex) const);\r
 \r
     /** Should return true if this parameter is a "meta" parameter.\r
         A meta-parameter is a parameter that changes other params. It is used\r
@@ -1143,7 +1172,7 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use\r
         AudioProcessorParameter::isMetaParameter() instead.\r
     */\r
-    virtual bool isMetaParameter (int parameterIndex) const;\r
+    JUCE_DEPRECATED (virtual bool isMetaParameter (int parameterIndex) const);\r
 \r
     /** Should return the parameter's category.\r
         By default, this returns the "generic" category.\r
@@ -1151,7 +1180,7 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use\r
         AudioProcessorParameter::getCategory() instead.\r
     */\r
-    virtual AudioProcessorParameter::Category getParameterCategory (int parameterIndex) const;\r
+    JUCE_DEPRECATED (virtual AudioProcessorParameter::Category getParameterCategory (int parameterIndex) const);\r
 \r
     /** Sends a signal to the host to tell it that the user is about to start changing this\r
         parameter.\r
@@ -1164,7 +1193,7 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use\r
         AudioProcessorParameter::beginChangeGesture() instead.\r
     */\r
-    void beginParameterChangeGesture (int parameterIndex);\r
+    JUCE_DEPRECATED (void beginParameterChangeGesture (int parameterIndex));\r
 \r
     /** Tells the host that the user has finished changing this parameter.\r
 \r
@@ -1176,7 +1205,7 @@ public:
         NOTE! This method will eventually be deprecated! It's recommended that you use\r
         AudioProcessorParameter::endChangeGesture() instead.\r
     */\r
-    void endParameterChangeGesture (int parameterIndex);\r
+    JUCE_DEPRECATED (void endParameterChangeGesture (int parameterIndex));\r
 \r
     /** The processor can call this when something (apart from a parameter value) has changed.\r
 \r
@@ -1626,8 +1655,6 @@ private:
     friend class AudioUnitPluginInstance;\r
     friend class LADSPAPluginInstance;\r
 \r
-    Atomic<int> vst3IsPlaying { 0 };\r
-\r
     // This method is no longer used - you can delete it from your AudioProcessor classes.\r
     JUCE_DEPRECATED_WITH_BODY (virtual bool silenceInProducesSilenceOut() const, { return false; })\r
 \r
index 336038dc17517cff1a7a5717a0e5c1cfa43091ab..8eedcb8ecff0009f25be176af69ba33b5b9ec5ca 100644 (file)
@@ -270,12 +270,20 @@ private:
             if (processor.isUsingDoublePrecision())\r
             {\r
                 tempBufferDouble.makeCopyOf (buffer, true);\r
-                processor.processBlock (tempBufferDouble, midiMessages);\r
+\r
+                if (node->isBypassed())\r
+                    processor.processBlockBypassed (tempBufferDouble, midiMessages);\r
+                else\r
+                    processor.processBlock (tempBufferDouble, midiMessages);\r
+\r
                 buffer.makeCopyOf (tempBufferDouble, true);\r
             }\r
             else\r
             {\r
-                processor.processBlock (buffer, midiMessages);\r
+                if (node->isBypassed())\r
+                    processor.processBlockBypassed (buffer, midiMessages);\r
+                else\r
+                    processor.processBlock (buffer, midiMessages);\r
             }\r
         }\r
 \r
@@ -283,12 +291,20 @@ private:
         {\r
             if (processor.isUsingDoublePrecision())\r
             {\r
-                processor.processBlock (buffer, midiMessages);\r
+                if (node->isBypassed())\r
+                    processor.processBlockBypassed (buffer, midiMessages);\r
+                else\r
+                    processor.processBlock (buffer, midiMessages);\r
             }\r
             else\r
             {\r
                 tempBufferFloat.makeCopyOf (buffer, true);\r
-                processor.processBlock (tempBufferFloat, midiMessages);\r
+\r
+                if (node->isBypassed())\r
+                    processor.processBlockBypassed (tempBufferFloat, midiMessages);\r
+                else\r
+                    processor.processBlock (tempBufferFloat, midiMessages);\r
+\r
                 buffer.makeCopyOf (tempBufferFloat, true);\r
             }\r
         }\r
@@ -826,6 +842,29 @@ bool AudioProcessorGraph::Node::Connection::operator== (const Connection& other)
         && otherChannel == other.otherChannel;\r
 }\r
 \r
+//==============================================================================\r
+bool AudioProcessorGraph::Node::isBypassed() const noexcept\r
+{\r
+    if (processor != nullptr)\r
+    {\r
+        if (auto* bypassParam = processor->getBypassParameter())\r
+            return (bypassParam->getValue() != 0.0f);\r
+    }\r
+\r
+    return bypassed;\r
+}\r
+\r
+void AudioProcessorGraph::Node::setBypassed (bool shouldBeBypassed) noexcept\r
+{\r
+    if (processor != nullptr)\r
+    {\r
+        if (auto* bypassParam = processor->getBypassParameter())\r
+            bypassParam->setValueNotifyingHost (shouldBeBypassed ? 1.0f : 0.0f);\r
+    }\r
+\r
+    bypassed = shouldBeBypassed;\r
+}\r
+\r
 //==============================================================================\r
 struct AudioProcessorGraph::RenderSequenceFloat   : public GraphRenderSequence<float> {};\r
 struct AudioProcessorGraph::RenderSequenceDouble  : public GraphRenderSequence<double> {};\r
index 0fac99ced17ed6fb77dae118f90cbe551b436deb..15983d30819e874f198ed6ae0887a7274280dd77 100644 (file)
@@ -108,6 +108,13 @@ public:
         */\r
         NamedValueSet properties;\r
 \r
+        //==============================================================================\r
+        /** Returns if the node is bypassed or not. */\r
+        bool isBypassed() const noexcept;\r
+\r
+        /** Tell this node to bypass processing. */\r
+        void setBypassed (bool shouldBeBypassed) noexcept;\r
+\r
         //==============================================================================\r
         /** A convenient typedef for referring to a pointer to a node object. */\r
         typedef ReferenceCountedObjectPtr<Node> Ptr;\r
@@ -126,7 +133,7 @@ public:
 \r
         const ScopedPointer<AudioProcessor> processor;\r
         Array<Connection> inputs, outputs;\r
-        bool isPrepared = false;\r
+        bool isPrepared = false, bypassed = false;\r
 \r
         Node (NodeID, AudioProcessor*) noexcept;\r
 \r
index 5d471375be840e0f233faaf705274f7e7cbfe124..3a302b2e1e020192eadbba315c7f6348f9c2583a 100644 (file)
 namespace juce\r
 {\r
 \r
-class ProcessorParameterPropertyComp   : public PropertyComponent,\r
-                                         private AudioProcessorListener,\r
-                                         private Timer\r
-{\r
-public:\r
-    ProcessorParameterPropertyComp (const String& name, AudioProcessor& p, int paramIndex)\r
-        : PropertyComponent (name),\r
-          owner (p),\r
-          index (paramIndex),\r
-          slider (p, paramIndex)\r
-    {\r
-        startTimer (100);\r
-        addAndMakeVisible (slider);\r
-        owner.addListener (this);\r
-    }\r
-\r
-    ~ProcessorParameterPropertyComp()\r
-    {\r
-        owner.removeListener (this);\r
-    }\r
-\r
-    void refresh() override\r
-    {\r
-        paramHasChanged = false;\r
-\r
-        if (slider.getThumbBeingDragged() < 0)\r
-            slider.setValue (owner.getParameter (index), dontSendNotification);\r
-\r
-        slider.updateText();\r
-    }\r
-\r
-    void audioProcessorChanged (AudioProcessor*) override  {}\r
-\r
-    void audioProcessorParameterChanged (AudioProcessor*, int parameterIndex, float) override\r
-    {\r
-        if (parameterIndex == index)\r
-            paramHasChanged = true;\r
-    }\r
-\r
-    void timerCallback() override\r
-    {\r
-        if (paramHasChanged)\r
-        {\r
-            refresh();\r
-            startTimerHz (50);\r
-        }\r
-        else\r
-        {\r
-            startTimer (jmin (1000 / 4, getTimerInterval() + 10));\r
-        }\r
-    }\r
-\r
-private:\r
-    //==============================================================================\r
-    class ParamSlider  : public Slider\r
-    {\r
-    public:\r
-        ParamSlider (AudioProcessor& p, int paramIndex)  : owner (p), index (paramIndex)\r
-        {\r
-            auto steps = owner.getParameterNumSteps (index);\r
-            auto category = p.getParameterCategory (index);\r
-            bool isLevelMeter = (((category & 0xffff0000) >> 16) == 2);\r
-\r
-            if (steps > 1 && steps < 0x7fffffff)\r
-                setRange (0.0, 1.0, 1.0 / (steps - 1.0));\r
-            else\r
-                setRange (0.0, 1.0);\r
-\r
-            setEnabled (! isLevelMeter);\r
-            setSliderStyle (Slider::LinearBar);\r
-            setTextBoxIsEditable (false);\r
-            setScrollWheelEnabled (true);\r
-        }\r
-\r
-        void valueChanged() override\r
-        {\r
-            auto newVal = static_cast<float> (getValue());\r
-\r
-            if (owner.getParameter (index) != newVal)\r
-            {\r
-                owner.setParameterNotifyingHost (index, newVal);\r
-                updateText();\r
-            }\r
-        }\r
-\r
-        void startedDragging() override\r
-        {\r
-            owner.beginParameterChangeGesture (index);\r
-        }\r
-\r
-        void stoppedDragging() override\r
-        {\r
-            owner.endParameterChangeGesture (index);\r
-        }\r
-\r
-        String getTextFromValue (double /*value*/) override\r
-        {\r
-            return (owner.getParameterText (index) + " " + owner.getParameterLabel (index)).trimEnd();\r
-        }\r
-\r
-    private:\r
-        //==============================================================================\r
-        AudioProcessor& owner;\r
-        const int index;\r
-\r
-        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParamSlider)\r
-    };\r
-\r
-    AudioProcessor& owner;\r
-    const int index;\r
-    bool volatile paramHasChanged = false;\r
-    ParamSlider slider;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProcessorParameterPropertyComp)\r
-};\r
-\r
-struct LegacyParametersPanel   : public Component\r
-{\r
-    LegacyParametersPanel (AudioProcessor* const processor)\r
-    {\r
-        addAndMakeVisible (panel);\r
-\r
-        Array<PropertyComponent*> params;\r
-\r
-        auto numParams = processor->getNumParameters();\r
-        int totalHeight = 0;\r
-\r
-        for (int i = 0; i < numParams; ++i)\r
-        {\r
-            String name (processor->getParameterName (i));\r
-\r
-            if (name.trim().isEmpty())\r
-                name = "Unnamed";\r
-\r
-            auto* pc = new ProcessorParameterPropertyComp (name, *processor, i);\r
-            params.add (pc);\r
-            totalHeight += pc->getPreferredHeight();\r
-        }\r
-\r
-        panel.addProperties (params);\r
-\r
-        setSize (400, jmax (25, totalHeight));\r
-    }\r
-\r
-    void paint (Graphics& g) override\r
-    {\r
-        g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r
-    }\r
-\r
-    void resized() override\r
-    {\r
-        panel.setBounds (getLocalBounds());\r
-    }\r
-\r
-    PropertyPanel panel;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LegacyParametersPanel)\r
-};\r
-\r
-//==============================================================================\r
 class ParameterListener   : private AudioProcessorParameter::Listener,\r
                             private Timer\r
 {\r
@@ -615,7 +455,7 @@ private:
 class ParametersPanel   : public Component\r
 {\r
 public:\r
-    ParametersPanel (const OwnedArray<AudioProcessorParameter>& parameters)\r
+    ParametersPanel (const Array<AudioProcessorParameter*>& parameters)\r
     {\r
         for (auto* param : parameters)\r
             if (param->isAutomatable())\r
@@ -647,24 +487,40 @@ private:
 };\r
 \r
 //==============================================================================\r
-GenericAudioProcessorEditor::GenericAudioProcessorEditor (AudioProcessor* const p)\r
-    : AudioProcessorEditor (p)\r
+struct  GenericAudioProcessorEditor::Pimpl\r
 {\r
-    jassert (p != nullptr);\r
-    setOpaque (true);\r
+    Pimpl (GenericAudioProcessorEditor& parent)\r
+        : owner (parent)\r
+    {\r
+        auto* p = parent.getAudioProcessor();\r
+        jassert (p != nullptr);\r
+\r
+        juceParameters.update (*p, false);\r
+\r
+        owner.setOpaque (true);\r
+\r
+        view.setViewedComponent (new ParametersPanel (juceParameters.params));\r
+        owner.addAndMakeVisible (view);\r
+\r
+        view.setScrollBarsShown (true, false);\r
+    }\r
 \r
-    auto& parameters = p->getParameters();\r
 \r
-    if (parameters.size() == p->getNumParameters())\r
-        view.setViewedComponent (new ParametersPanel (parameters));\r
-    else\r
-        view.setViewedComponent (new LegacyParametersPanel (p));\r
+    //==============================================================================\r
+    GenericAudioProcessorEditor& owner;\r
+    LegacyAudioParametersWrapper juceParameters;\r
+    Viewport view;\r
+\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)\r
+};\r
 \r
-    addAndMakeVisible (view);\r
 \r
-    view.setScrollBarsShown (true, false);\r
-    setSize (view.getViewedComponent()->getWidth() + view.getVerticalScrollBar().getWidth(),\r
-             jmin (view.getViewedComponent()->getHeight(), 400));\r
+//==============================================================================\r
+GenericAudioProcessorEditor::GenericAudioProcessorEditor (AudioProcessor* const p)\r
+    : AudioProcessorEditor (p), pimpl (new Pimpl (*this))\r
+{\r
+    setSize (pimpl->view.getViewedComponent()->getWidth() + pimpl->view.getVerticalScrollBar().getWidth(),\r
+             jmin (pimpl->view.getViewedComponent()->getHeight(), 400));\r
 }\r
 \r
 GenericAudioProcessorEditor::~GenericAudioProcessorEditor() {}\r
@@ -676,7 +532,7 @@ void GenericAudioProcessorEditor::paint (Graphics& g)
 \r
 void GenericAudioProcessorEditor::resized()\r
 {\r
-    view.setBounds (getLocalBounds());\r
+    pimpl->view.setBounds (getLocalBounds());\r
 }\r
 \r
 } // namespace juce\r
index 9945f20b5ebb7af3e1166f90bce8d8f73d118d5b..c79be1b5fee4802a0c9624617f2dcfc087a92f35 100644 (file)
@@ -52,7 +52,8 @@ public:
 \r
 private:\r
     //==============================================================================\r
-    Viewport view;\r
+    struct Pimpl;\r
+    ScopedPointer<Pimpl> pimpl;\r
 \r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GenericAudioProcessorEditor)\r
 };\r
index 3dc83c635bf8a0b483149a1b361a93ffe7e7d336..955a44ecf56287dbb4429d1294d8694ed1a6d008 100644 (file)
@@ -38,14 +38,16 @@ struct AudioProcessorValueTreeState::Parameter   : public AudioProcessorParamete
                bool meta,\r
                bool automatable,\r
                bool discrete,\r
-               AudioProcessorParameter::Category category)\r
+               AudioProcessorParameter::Category category,\r
+               bool boolean)\r
         : AudioProcessorParameterWithID (parameterID, paramName, labelText, category),\r
           owner (s), valueToTextFunction (valueToText), textToValueFunction (textToValue),\r
           range (r), value (defaultVal), defaultValue (defaultVal),\r
           listenersNeedCalling (true),\r
           isMetaParam (meta),\r
           isAutomatableParam (automatable),\r
-          isDiscreteParam (discrete)\r
+          isDiscreteParam (discrete),\r
+          isBooleanParam (boolean)\r
     {\r
         state.addListener (this);\r
         needsUpdate.set (1);\r
@@ -152,6 +154,7 @@ struct AudioProcessorValueTreeState::Parameter   : public AudioProcessorParamete
     bool isMetaParameter() const override      { return isMetaParam; }\r
     bool isAutomatable() const override        { return isAutomatableParam; }\r
     bool isDiscrete() const override           { return isDiscreteParam; }\r
+    bool isBoolean() const override            { return isBooleanParam; }\r
 \r
     AudioProcessorValueTreeState& owner;\r
     ValueTree state;\r
@@ -162,7 +165,7 @@ struct AudioProcessorValueTreeState::Parameter   : public AudioProcessorParamete
     float value, defaultValue;\r
     Atomic<int> needsUpdate;\r
     bool listenersNeedCalling;\r
-    const bool isMetaParam, isAutomatableParam, isDiscreteParam;\r
+    const bool isMetaParam, isAutomatableParam, isDiscreteParam, isBooleanParam;\r
 \r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Parameter)\r
 };\r
@@ -184,7 +187,8 @@ AudioProcessorParameterWithID* AudioProcessorValueTreeState::createAndAddParamet
                                                                                     bool isMetaParameter,\r
                                                                                     bool isAutomatableParameter,\r
                                                                                     bool isDiscreteParameter,\r
-                                                                                    AudioProcessorParameter::Category category)\r
+                                                                                    AudioProcessorParameter::Category category,\r
+                                                                                    bool isBooleanParameter)\r
 {\r
     // All parameters must be created before giving this manager a ValueTree state!\r
     jassert (! state.isValid());\r
@@ -192,7 +196,7 @@ AudioProcessorParameterWithID* AudioProcessorValueTreeState::createAndAddParamet
     Parameter* p = new Parameter (*this, paramID, paramName, labelText, r,\r
                                   defaultVal, valueToTextFunction, textToValueFunction,\r
                                   isMetaParameter, isAutomatableParameter,\r
-                                  isDiscreteParameter, category);\r
+                                  isDiscreteParameter, category, isBooleanParameter);\r
     processor.addParameter (p);\r
     return p;\r
 }\r
index 9813eed1b773c7c7fa217ed9eb7cd75b3c6aeef1..70fc72f52993e5ec39b1bf33a98eea433dc16803 100644 (file)
@@ -84,6 +84,9 @@ public:
                                         @see AudioProcessorParameter::isDiscrete\r
         @param category                 Which category the parameter should use.\r
                                         @see AudioProcessorParameter::Category\r
+        @param isBoolean                Set this value to true to make this parameter appear as a boolean toggle in\r
+                                        a hosts view of your plug-ins parameters\r
+                                        @see AudioProcessorParameter::isBoolean\r
 \r
         @returns the parameter object that was created\r
     */\r
@@ -98,7 +101,8 @@ public:
                                                           bool isAutomatableParameter = true,\r
                                                           bool isDiscrete = false,\r
                                                           AudioProcessorParameter::Category category\r
-                                                             = AudioProcessorParameter::genericParameter);\r
+                                                             = AudioProcessorParameter::genericParameter,\r
+                                                          bool isBoolean = false);\r
 \r
     /** Returns a parameter by its ID string. */\r
     AudioProcessorParameterWithID* getParameter (StringRef parameterID) const noexcept;\r
index 7802258245792d7deb2c17c9ad7d6a685fa7b91d..392692ad25f08b7b95394a323513fcb45e06c388 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_audio_utils\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE extra audio utility classes\r
   description:      Classes for audio-related GUI and miscellaneous tasks.\r
   website:          http://www.juce.com/juce\r
index 80298258946d1e29d9dafbcff85ba9586bf391ff..a260f32de45c326705eea9a554f5b2ff1eb0b34a 100644 (file)
@@ -31,7 +31,7 @@
 \r
   ID:               juce_blocks_basics\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             Provides low-level control over ROLI BLOCKS devices\r
   description:      JUCE wrapper for low-level control over ROLI BLOCKS devices.\r
   website:          http://developer.roli.com\r
index cc9f787f872b458a42799182e76e7a6101ae6ca0..a3d06abd014a349a77d2f18bc8909c10db7db865 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_box2d\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE wrapper for the Box2D physics engine\r
   description:      The Box2D physics engine and some utility classes.\r
   website:          http://www.juce.com/juce\r
index 6e0f24c2e31c02b01db3da617df46f4c6d4c6d2a..8ce16acd56b45dba106d6e414d93d104b4ae8456 100644 (file)
@@ -82,12 +82,17 @@ static void sortArray (ElementComparator& comparator,
                        int lastElement,\r
                        const bool retainOrderOfEquivalentItems)\r
 {\r
-    SortFunctionConverter<ElementComparator> converter (comparator);\r
+    jassert (firstElement >= 0);\r
 \r
-    if (retainOrderOfEquivalentItems)\r
-        std::stable_sort (array + firstElement, array + lastElement + 1, converter);\r
-    else\r
-        std::sort        (array + firstElement, array + lastElement + 1, converter);\r
+    if (lastElement > firstElement)\r
+    {\r
+        SortFunctionConverter<ElementComparator> converter (comparator);\r
+\r
+        if (retainOrderOfEquivalentItems)\r
+            std::stable_sort (array + firstElement, array + lastElement + 1, converter);\r
+        else\r
+            std::sort        (array + firstElement, array + lastElement + 1, converter);\r
+    }\r
 }\r
 \r
 \r
index 077b8d6585f7cabc65911ed8086ff07912c63f8c..d1c0d2c8361bcc470ff519f505fb55c66cf4f35d 100644 (file)
@@ -46,23 +46,17 @@ public:
     SparseSet (const SparseSet&) = default;\r
     SparseSet& operator= (const SparseSet&) = default;\r
 \r
-    SparseSet (SparseSet&& other) noexcept : values (static_cast<Array<Type, DummyCriticalSection>&&> (other.values)) {}\r
-    SparseSet& operator= (SparseSet&& other) noexcept { values = static_cast<Array<Type, DummyCriticalSection>&&> (other.values); return *this; }\r
+    SparseSet (SparseSet&& other) noexcept : ranges (static_cast<Array<Range<Type>>&&> (other.ranges)) {}\r
+    SparseSet& operator= (SparseSet&& other) noexcept { ranges = static_cast<Array<Range<Type>>&&> (other.ranges); return *this; }\r
 \r
     //==============================================================================\r
     /** Clears the set. */\r
-    void clear()\r
-    {\r
-        values.clear();\r
-    }\r
+    void clear()                                { ranges.clear(); }\r
 \r
     /** Checks whether the set is empty.\r
         This is much quicker than using (size() == 0).\r
     */\r
-    bool isEmpty() const noexcept\r
-    {\r
-        return values.isEmpty();\r
-    }\r
+    bool isEmpty() const noexcept               { return ranges.isEmpty(); }\r
 \r
     /** Returns the number of values in the set.\r
 \r
@@ -74,8 +68,8 @@ public:
     {\r
         Type total = {};\r
 \r
-        for (int i = 0; i < values.size(); i += 2)\r
-            total += values.getUnchecked (i + 1) - values.getUnchecked (i);\r
+        for (auto& r : ranges)\r
+            total += r.getLength();\r
 \r
         return total;\r
     }\r
@@ -87,26 +81,32 @@ public:
     */\r
     Type operator[] (Type index) const noexcept\r
     {\r
-        for (int i = 0; i < values.size(); i += 2)\r
+        Type total = {};\r
+\r
+        for (auto& r : ranges)\r
         {\r
-            auto start = values.getUnchecked (i);\r
-            auto len = values.getUnchecked (i + 1) - start;\r
+            auto end = total + r.getLength();\r
 \r
-            if (index < len)\r
-                return start + index;\r
+            if (index < end)\r
+                return r.getStart() + (index - total);\r
 \r
-            index -= len;\r
+            total = end;\r
         }\r
 \r
-        return Type();\r
+        return {};\r
     }\r
 \r
     /** Checks whether a particular value is in the set. */\r
     bool contains (Type valueToLookFor) const noexcept\r
     {\r
-        for (int i = 0; i < values.size(); ++i)\r
-            if (valueToLookFor < values.getUnchecked(i))\r
-                return (i & 1) != 0;\r
+        for (auto& r : ranges)\r
+        {\r
+            if (r.getStart() > valueToLookFor)\r
+                break;\r
+\r
+            if (r.getEnd() > valueToLookFor)\r
+                return true;\r
+        }\r
 \r
         return false;\r
     }\r
@@ -115,37 +115,25 @@ public:
     /** Returns the number of contiguous blocks of values.\r
         @see getRange\r
     */\r
-    int getNumRanges() const noexcept\r
-    {\r
-        return values.size() >> 1;\r
-    }\r
+    int getNumRanges() const noexcept                           { return ranges.size(); }\r
 \r
     /** Returns one of the contiguous ranges of values stored.\r
         @param rangeIndex   the index of the range to look up, between 0\r
                             and (getNumRanges() - 1)\r
         @see getTotalRange\r
     */\r
-    const Range<Type> getRange (int rangeIndex) const noexcept\r
-    {\r
-        if (isPositiveAndBelow (rangeIndex, getNumRanges()))\r
-            return { values.getUnchecked (rangeIndex << 1),\r
-                     values.getUnchecked ((rangeIndex << 1) + 1) };\r
-\r
-        return {};\r
-    }\r
+    Range<Type> getRange (int rangeIndex) const noexcept        { return ranges[rangeIndex]; }\r
 \r
     /** Returns the range between the lowest and highest values in the set.\r
         @see getRange\r
     */\r
     Range<Type> getTotalRange() const noexcept\r
     {\r
-        if (auto num = values.size())\r
-        {\r
-            jassert ((num & 1) == 0);\r
-            return { values.getUnchecked (0), values.getUnchecked (num - 1) };\r
-        }\r
+        if (ranges.isEmpty())\r
+            return {};\r
 \r
-        return {};\r
+        return { ranges.getFirst().getStart(),\r
+                 ranges.getLast().getEnd() };\r
     }\r
 \r
     //==============================================================================\r
@@ -157,10 +145,9 @@ public:
         if (! range.isEmpty())\r
         {\r
             removeRange (range);\r
-\r
-            values.addUsingDefaultSort (range.getStart());\r
-            values.addUsingDefaultSort (range.getEnd());\r
-\r
+            ranges.add (range);\r
+            std::sort (ranges.begin(), ranges.end(),\r
+                       [] (Range<Type> a, Range<Type> b) { return a.getStart() < b.getStart(); });\r
             simplify();\r
         }\r
     }\r
@@ -170,35 +157,37 @@ public:
     */\r
     void removeRange (Range<Type> rangeToRemove)\r
     {\r
-        if (rangeToRemove.getLength() > 0\r
-             && values.size() > 0\r
-             && rangeToRemove.getStart() < values.getUnchecked (values.size() - 1)\r
-             && values.getUnchecked(0) < rangeToRemove.getEnd())\r
+        if (getTotalRange().intersects (rangeToRemove) && ! rangeToRemove.isEmpty())\r
         {\r
-            bool onAtStart = contains (rangeToRemove.getStart() - 1);\r
-            auto lastValue = jmin (rangeToRemove.getEnd(), values.getLast());\r
-            bool onAtEnd = contains (lastValue);\r
-\r
-            for (int i = values.size(); --i >= 0;)\r
+            for (int i = ranges.size(); --i >= 0;)\r
             {\r
-                if (values.getUnchecked(i) <= lastValue)\r
-                {\r
-                    while (values.getUnchecked(i) >= rangeToRemove.getStart())\r
-                    {\r
-                        values.remove (i);\r
-\r
-                        if (--i < 0)\r
-                            break;\r
-                    }\r
+                auto& r = ranges.getReference(i);\r
 \r
+                if (r.getEnd() <= rangeToRemove.getStart())\r
                     break;\r
-                }\r
-            }\r
 \r
-            if (onAtStart)   values.addUsingDefaultSort (rangeToRemove.getStart());\r
-            if (onAtEnd)     values.addUsingDefaultSort (lastValue);\r
+                if (r.getStart() >= rangeToRemove.getEnd())\r
+                    continue;\r
 \r
-            simplify();\r
+                if (r.contains (rangeToRemove))\r
+                {\r
+                    auto start = r.withEnd (rangeToRemove.getStart());\r
+                    r.setStart (rangeToRemove.getEnd());\r
+                    ranges.insert (i, start);\r
+                }\r
+                else if (rangeToRemove.contains (r))\r
+                {\r
+                    ranges.remove (i);\r
+                }\r
+                else if (rangeToRemove.getEnd() > r.getStart())\r
+                {\r
+                    r.setStart (rangeToRemove.getEnd());\r
+                }\r
+                else\r
+                {\r
+                    r.setEnd (rangeToRemove.getStart());\r
+                }\r
+            }\r
         }\r
     }\r
 \r
@@ -208,29 +197,22 @@ public:
         SparseSet newItems;\r
         newItems.addRange (range);\r
 \r
-        for (int i = getNumRanges(); --i >= 0;)\r
-            newItems.removeRange (getRange (i));\r
+        for (auto& r : ranges)\r
+            newItems.removeRange (r);\r
 \r
         removeRange (range);\r
 \r
-        for (int i = newItems.getNumRanges(); --i >= 0;)\r
-            addRange (newItems.getRange(i));\r
+        for (auto& r : newItems.ranges)\r
+            addRange (r);\r
     }\r
 \r
     /** Checks whether any part of a given range overlaps any part of this set. */\r
     bool overlapsRange (Range<Type> range) const noexcept\r
     {\r
-        if (range.getLength() > 0)\r
-        {\r
-            for (int i = getNumRanges(); --i >= 0;)\r
-            {\r
-                if (values.getUnchecked ((i << 1) + 1) <= range.getStart())\r
-                    return false;\r
-\r
-                if (values.getUnchecked (i << 1) < range.getEnd())\r
+        if (! range.isEmpty())\r
+            for (auto& r : ranges)\r
+                if (r.intersects (range))\r
                     return true;\r
-            }\r
-        }\r
 \r
         return false;\r
     }\r
@@ -238,38 +220,38 @@ public:
     /** Checks whether the whole of a given range is contained within this one. */\r
     bool containsRange (Range<Type> range) const noexcept\r
     {\r
-        if (range.getLength() > 0)\r
-        {\r
-            for (int i = getNumRanges(); --i >= 0;)\r
-            {\r
-                if (values.getUnchecked ((i << 1) + 1) <= range.getStart())\r
-                    return false;\r
-\r
-                if (values.getUnchecked (i << 1) <= range.getStart()\r
-                     && range.getEnd() <= values.getUnchecked ((i << 1) + 1))\r
+        if (! range.isEmpty())\r
+            for (auto& r : ranges)\r
+                if (r.contains (range))\r
                     return true;\r
-            }\r
-        }\r
 \r
         return false;\r
     }\r
 \r
+    /** Returns the set as a list of ranges, which you may want to iterate over. */\r
+    const Array<Range<Type>>& getRanges() const noexcept        { return ranges; }\r
+\r
     //==============================================================================\r
-    bool operator== (const SparseSet& other) const noexcept    { return values == other.values; }\r
-    bool operator!= (const SparseSet& other) const noexcept    { return values != other.values; }\r
+    bool operator== (const SparseSet& other) const noexcept     { return ranges == other.ranges; }\r
+    bool operator!= (const SparseSet& other) const noexcept     { return ranges != other.ranges; }\r
 \r
 private:\r
     //==============================================================================\r
-    // alternating start/end values of ranges of values that are present.\r
-    Array<Type, DummyCriticalSection> values;\r
+    Array<Range<Type>> ranges;\r
 \r
     void simplify()\r
     {\r
-        jassert ((values.size() & 1) == 0);\r
+        for (int i = ranges.size(); --i > 0;)\r
+        {\r
+            auto& r1 = ranges.getReference (i - 1);\r
+            auto& r2 = ranges.getReference (i);\r
 \r
-        for (int i = values.size(); --i > 0;)\r
-            if (values.getUnchecked(i) == values.getUnchecked (i - 1))\r
-                values.removeRange (--i, 2);\r
+            if (r1.getEnd() == r2.getStart())\r
+            {\r
+                r1.setEnd (r2.getEnd());\r
+                ranges.remove (i);\r
+            }\r
+        }\r
     }\r
 };\r
 \r
index d7ded1c2125a13bc688b3b0f6b3d0f399026595e..358edd27492b835b3fa47038f3bb10392a14c0d0 100644 (file)
@@ -941,7 +941,9 @@ File File::createTempFile (StringRef fileNameEnding)
     return tempFile;\r
 }\r
 \r
-bool File::createSymbolicLink (const File& linkFileToCreate, bool overwriteExisting) const\r
+bool File::createSymbolicLink (const File& linkFileToCreate,\r
+                               const String& nativePathOfTarget,\r
+                               bool overwriteExisting)\r
 {\r
     if (linkFileToCreate.exists())\r
     {\r
@@ -959,7 +961,7 @@ bool File::createSymbolicLink (const File& linkFileToCreate, bool overwriteExist
 \r
    #if JUCE_MAC || JUCE_LINUX\r
     // one common reason for getting an error here is that the file already exists\r
-    if (symlink (fullPath.toRawUTF8(), linkFileToCreate.getFullPathName().toRawUTF8()) == -1)\r
+    if (symlink (nativePathOfTarget.toRawUTF8(), linkFileToCreate.getFullPathName().toRawUTF8()) == -1)\r
     {\r
         jassertfalse;\r
         return false;\r
@@ -967,15 +969,32 @@ bool File::createSymbolicLink (const File& linkFileToCreate, bool overwriteExist
 \r
     return true;\r
    #elif JUCE_MSVC\r
+    File targetFile (linkFileToCreate.getSiblingFile (nativePathOfTarget));\r
+\r
     return CreateSymbolicLink (linkFileToCreate.getFullPathName().toWideCharPointer(),\r
-                               fullPath.toWideCharPointer(),\r
-                               isDirectory() ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) != FALSE;\r
+                               nativePathOfTarget.toWideCharPointer(),\r
+                               targetFile.isDirectory() ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) != FALSE;\r
    #else\r
     jassertfalse; // symbolic links not supported on this platform!\r
     return false;\r
    #endif\r
 }\r
 \r
+bool File::createSymbolicLink (const File& linkFileToCreate, bool overwriteExisting) const\r
+{\r
+    return createSymbolicLink (linkFileToCreate, getFullPathName(), overwriteExisting);\r
+}\r
+\r
+#if ! JUCE_WINDOWS\r
+File File::getLinkedTarget() const\r
+{\r
+    if (isSymbolicLink())\r
+        return getSiblingFile (getNativeLinkedTarget());\r
+\r
+    return *this;\r
+}\r
+#endif\r
+\r
 //==============================================================================\r
 MemoryMappedFile::MemoryMappedFile (const File& file, MemoryMappedFile::AccessMode mode, bool exclusive)\r
     : range (0, file.getSize())\r
index fd52a39d300abd0844981b2684e5688cebca2136..5f7d2d1b29465f1e3e75f9c1b4095ae7b41252b0 100644 (file)
@@ -987,12 +987,27 @@ public:
     */\r
     File getLinkedTarget() const;\r
 \r
+    /** Create a symbolic link to a native path and return a boolean to indicate success.\r
+\r
+        Use this method if you want to create a link to a relative path or a special native\r
+        file path (such as a device file on Windows).\r
+    */\r
+    static bool createSymbolicLink (const File& linkFileToCreate,\r
+                                    const String& nativePathOfTarget,\r
+                                    bool overwriteExisting);\r
+\r
+    /** This returns the native path that the symbolic link points to. The returned path\r
+        is a native path of the current OS and can be a relative, absolute or special path. */\r
+    String getNativeLinkedTarget() const;\r
+\r
    #if JUCE_WINDOWS || DOXYGEN\r
     /** Windows ONLY - Creates a win32 .LNK shortcut file that links to this file. */\r
     bool createShortcut (const String& description, const File& linkFileToCreate) const;\r
 \r
     /** Windows ONLY - Returns true if this is a win32 .LNK file. */\r
     bool isShortcut() const;\r
+   #else\r
+\r
    #endif\r
 \r
     //==============================================================================\r
index 0c2326d03c95a5f546c89542eb3e3b1fe90a989e..275b633066f91e6b3f66756370149c3f92a5ab43 100644 (file)
@@ -32,7 +32,7 @@
 \r
   ID:               juce_core\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE core classes\r
   description:      The essential set of basic JUCE classes, as required by all the other JUCE modules. Includes text, container, memory, threading and i/o functionality.\r
   website:          http://www.juce.com/juce\r
index 01962e1211ca337273fe8ce3f25ce8084d75e097..83d2ce225b3601ccf3d920f595b7cd0835c412e1 100644 (file)
@@ -387,7 +387,7 @@ const FloatType MathConstants<FloatType>::sqrt2 = static_cast<FloatType> (1.4142
 \r
 #endif\r
 \r
-\r
+#ifndef DOXYGEN\r
 /** A double-precision constant for pi.\r
     @deprecated This is deprecated in favour of MathConstants<double>::pi.\r
     The reason is that "double_Pi" was a confusing name, and many people misused it,\r
@@ -401,7 +401,7 @@ const JUCE_CONSTEXPR double  double_Pi  = MathConstants<double>::pi;
     wrongly thinking it meant 2 * pi !\r
 */\r
 const JUCE_CONSTEXPR float   float_Pi   = MathConstants<float>::pi;\r
-\r
+#endif\r
 \r
 /** Converts an angle in degrees to radians. */\r
 template <typename FloatType>\r
index 4ba72f4db588366540f2f99f7dc8a370db85cd37..f4ff23ee5f04850f75e1f5ed63b3a4a9ec6a6219 100644 (file)
@@ -143,9 +143,9 @@ public:
     ValueType convertTo0to1 (ValueType v) const noexcept\r
     {\r
         if (convertTo0To1Function != nullptr)\r
-            return convertTo0To1Function (start, end, v);\r
+            return clampTo0To1 (convertTo0To1Function (start, end, v));\r
 \r
-        auto proportion = (v - start) / (end - start);\r
+        auto proportion = clampTo0To1 ((v - start) / (end - start));\r
 \r
         if (skew == static_cast<ValueType> (1))\r
             return proportion;\r
@@ -166,6 +166,8 @@ public:
     */\r
     ValueType convertFrom0to1 (ValueType proportion) const noexcept\r
     {\r
+        proportion = clampTo0To1 (proportion);\r
+\r
         if (convertFrom0To1Function != nullptr)\r
             return convertFrom0To1Function (start, end, proportion);\r
 \r
@@ -261,6 +263,17 @@ private:
         jassert (skew > ValueType());\r
     }\r
 \r
+    static ValueType clampTo0To1 (ValueType value)\r
+    {\r
+        auto clampedValue = jlimit (static_cast<ValueType> (0), static_cast<ValueType> (1), value);\r
+\r
+        // If you his this assertion then either your normalisation function is not working\r
+        // correctly or your input is out of the expected bounds.\r
+        jassert (clampedValue == value);\r
+\r
+        return clampedValue;\r
+    }\r
+\r
     typedef std::function<ValueType(ValueType, ValueType, ValueType)> ConverstionFunction;\r
     ConverstionFunction convertFrom0To1Function  = {},\r
                         convertTo0To1Function    = {},\r
index 2d11572cc01ec16e795ed7aaeafaba630fa43f8d..95e28482fb39b7513f3a9ad6980222a625b8d1f1 100644 (file)
@@ -36,117 +36,121 @@ public:
     /** Swaps the upper and lower bytes of a 16-bit integer. */\r
     JUCE_CONSTEXPR static uint16 swap (uint16 value) noexcept;\r
 \r
+    /** Swaps the upper and lower bytes of a 16-bit integer. */\r
+    JUCE_CONSTEXPR static int16 swap (int16 value) noexcept;\r
+\r
     /** Reverses the order of the 4 bytes in a 32-bit integer. */\r
     static uint32 swap (uint32 value) noexcept;\r
 \r
+    /** Reverses the order of the 4 bytes in a 32-bit integer. */\r
+    static int32 swap (int32 value) noexcept;\r
+\r
     /** Reverses the order of the 8 bytes in a 64-bit integer. */\r
     static uint64 swap (uint64 value) noexcept;\r
 \r
-    //==============================================================================\r
-    /** Swaps the byte order of a 16-bit unsigned int if the CPU is big-endian */\r
-    JUCE_CONSTEXPR static uint16 swapIfBigEndian (uint16 value) noexcept;\r
-\r
-    /** Swaps the byte order of a 32-bit unsigned int if the CPU is big-endian */\r
-    static uint32 swapIfBigEndian (uint32 value) noexcept;\r
-\r
-    /** Swaps the byte order of a 64-bit unsigned int if the CPU is big-endian */\r
-    static uint64 swapIfBigEndian (uint64 value) noexcept;\r
-\r
-    /** Swaps the byte order of a 16-bit signed int if the CPU is big-endian */\r
-    JUCE_CONSTEXPR static int16 swapIfBigEndian (int16 value) noexcept;\r
-\r
-    /** Swaps the byte order of a 32-bit signed int if the CPU is big-endian */\r
-    static int32 swapIfBigEndian (int32 value) noexcept;\r
-\r
-    /** Swaps the byte order of a 64-bit signed int if the CPU is big-endian */\r
-    static int64 swapIfBigEndian (int64 value) noexcept;\r
-\r
-    /** Swaps the byte order of a 32-bit float if the CPU is big-endian */\r
-    static float swapIfBigEndian (float value) noexcept;\r
-\r
-    /** Swaps the byte order of a 64-bit float if the CPU is big-endian */\r
-    static double swapIfBigEndian (double value) noexcept;\r
-\r
-    /** Swaps the byte order of a 16-bit unsigned int if the CPU is little-endian */\r
-    JUCE_CONSTEXPR static uint16 swapIfLittleEndian (uint16 value) noexcept;\r
-\r
-    /** Swaps the byte order of a 32-bit unsigned int if the CPU is little-endian */\r
-    static uint32 swapIfLittleEndian (uint32 value) noexcept;\r
-\r
-    /** Swaps the byte order of a 64-bit unsigned int if the CPU is little-endian */\r
-    static uint64 swapIfLittleEndian (uint64 value) noexcept;\r
-\r
-    /** Swaps the byte order of a 16-bit signed int if the CPU is little-endian */\r
-    JUCE_CONSTEXPR static int16 swapIfLittleEndian (int16 value) noexcept;\r
-\r
-    /** Swaps the byte order of a 32-bit signed int if the CPU is little-endian */\r
-    static int32 swapIfLittleEndian (int32 value) noexcept;\r
+    /** Reverses the order of the 8 bytes in a 64-bit integer. */\r
+    static int64 swap (int64 value) noexcept;\r
 \r
-    /** Swaps the byte order of a 64-bit signed int if the CPU is little-endian */\r
-    static int64 swapIfLittleEndian (int64 value) noexcept;\r
+    /** Returns a garbled float which has the reverse byte-order of the original. */\r
+    static float swap (float value) noexcept;\r
 \r
-    /** Swaps the byte order of a 32-bit float if the CPU is little-endian */\r
-    static float swapIfLittleEndian (float value) noexcept;\r
+    /** Returns a garbled double which has the reverse byte-order of the original. */\r
+    static double swap (double value) noexcept;\r
 \r
-    /** Swaps the byte order of a 64-bit float if the CPU is little-endian */\r
-    static double swapIfLittleEndian (double value) noexcept;\r
+    //==============================================================================\r
+    /** Swaps the byte order of a signed or unsigned integer if the CPU is big-endian */\r
+    template <typename Type>\r
+    static Type swapIfBigEndian (Type value) noexcept\r
+    {\r
+       #if JUCE_LITTLE_ENDIAN\r
+        return value;\r
+       #else\r
+        return swap (value);\r
+       #endif\r
+    }\r
+\r
+    /** Swaps the byte order of a signed or unsigned integer if the CPU is little-endian */\r
+    template <typename Type>\r
+    static Type swapIfLittleEndian (Type value) noexcept\r
+    {\r
+       #if JUCE_LITTLE_ENDIAN\r
+        return swap (value);\r
+       #else\r
+        return value;\r
+       #endif\r
+    }\r
 \r
     //==============================================================================\r
     /** Turns 4 bytes into a little-endian integer. */\r
-    static uint32 littleEndianInt (const void* bytes) noexcept;\r
-\r
-    /** Turns 4 characters into a little-endian integer. */\r
-    JUCE_CONSTEXPR static uint32 littleEndianInt (char c1, char c2, char c3, char c4) noexcept;\r
+    JUCE_CONSTEXPR static uint32 littleEndianInt (const void* bytes) noexcept;\r
 \r
     /** Turns 8 bytes into a little-endian integer. */\r
-    static uint64 littleEndianInt64 (const void* bytes) noexcept;\r
+    JUCE_CONSTEXPR static uint64 littleEndianInt64 (const void* bytes) noexcept;\r
 \r
     /** Turns 2 bytes into a little-endian integer. */\r
-    static uint16 littleEndianShort (const void* bytes) noexcept;\r
+    JUCE_CONSTEXPR static uint16 littleEndianShort (const void* bytes) noexcept;\r
+\r
+    /** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */\r
+    JUCE_CONSTEXPR static int littleEndian24Bit (const void* bytes) noexcept;\r
+\r
+    /** Copies a 24-bit number to 3 little-endian bytes. */\r
+    static void littleEndian24BitToChars (int32 value, void* destBytes) noexcept;\r
 \r
+    //==============================================================================\r
     /** Turns 4 bytes into a big-endian integer. */\r
-    static uint32 bigEndianInt (const void* bytes) noexcept;\r
+    JUCE_CONSTEXPR static uint32 bigEndianInt (const void* bytes) noexcept;\r
 \r
     /** Turns 8 bytes into a big-endian integer. */\r
-    static uint64 bigEndianInt64 (const void* bytes) noexcept;\r
+    JUCE_CONSTEXPR static uint64 bigEndianInt64 (const void* bytes) noexcept;\r
 \r
     /** Turns 2 bytes into a big-endian integer. */\r
-    static uint16 bigEndianShort (const void* bytes) noexcept;\r
-\r
-    //==============================================================================\r
-    /** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */\r
-    static int littleEndian24Bit (const void* bytes) noexcept;\r
+    JUCE_CONSTEXPR static uint16 bigEndianShort (const void* bytes) noexcept;\r
 \r
     /** Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */\r
-    static int bigEndian24Bit (const void* bytes) noexcept;\r
-\r
-    /** Copies a 24-bit number to 3 little-endian bytes. */\r
-    static void littleEndian24BitToChars (int value, void* destBytes) noexcept;\r
+    JUCE_CONSTEXPR static int bigEndian24Bit (const void* bytes) noexcept;\r
 \r
     /** Copies a 24-bit number to 3 big-endian bytes. */\r
-    static void bigEndian24BitToChars (int value, void* destBytes) noexcept;\r
+    static void bigEndian24BitToChars (int32 value, void* destBytes) noexcept;\r
+\r
+    //==============================================================================\r
+    /** Constructs a 16-bit integer from its constituent bytes, in order of significance. */\r
+    JUCE_CONSTEXPR static uint16 makeInt (uint8 leastSig, uint8 mostSig) noexcept;\r
+\r
+    /** Constructs a 32-bit integer from its constituent bytes, in order of significance. */\r
+    JUCE_CONSTEXPR static uint32 makeInt (uint8 leastSig, uint8 byte1, uint8 byte2, uint8 mostSig) noexcept;\r
+\r
+    /** Constructs a 64-bit integer from its constituent bytes, in order of significance. */\r
+    JUCE_CONSTEXPR static uint64 makeInt (uint8 leastSig, uint8 byte1, uint8 byte2, uint8 byte3,\r
+                                          uint8 byte4, uint8 byte5, uint8 byte6, uint8 mostSig) noexcept;\r
 \r
     //==============================================================================\r
     /** Returns true if the current CPU is big-endian. */\r
-    JUCE_CONSTEXPR static bool isBigEndian() noexcept;\r
+    JUCE_CONSTEXPR static bool isBigEndian() noexcept\r
+    {\r
+       #if JUCE_LITTLE_ENDIAN\r
+        return false;\r
+       #else\r
+        return true;\r
+       #endif\r
+    }\r
 \r
 private:\r
     ByteOrder() = delete;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE (ByteOrder)\r
 };\r
 \r
 \r
 //==============================================================================\r
+JUCE_CONSTEXPR inline uint16 ByteOrder::swap (uint16 v) noexcept    { return static_cast<uint16> ((v << 8) | (v >> 8)); }\r
+JUCE_CONSTEXPR inline int16  ByteOrder::swap (int16  v) noexcept    { return static_cast<int16> (swap (static_cast<uint16> (v))); }\r
+inline int32  ByteOrder::swap (int32 v) noexcept                    { return static_cast<int32> (swap (static_cast<uint32> (v))); }\r
+inline int64  ByteOrder::swap (int64 v) noexcept                    { return static_cast<int64> (swap (static_cast<uint64> (v))); }\r
+inline float  ByteOrder::swap (float v) noexcept                    { union { uint32 asUInt; float asFloat;  } n; n.asFloat = v; n.asUInt = swap (n.asUInt); return n.asFloat; }\r
+inline double ByteOrder::swap (double v) noexcept                   { union { uint64 asUInt; double asFloat; } n; n.asFloat = v; n.asUInt = swap (n.asUInt); return n.asFloat; }\r
+\r
 #if JUCE_MSVC && ! defined (__INTEL_COMPILER)\r
  #pragma intrinsic (_byteswap_ulong)\r
 #endif\r
 \r
-JUCE_CONSTEXPR inline uint16 ByteOrder::swap (uint16 n) noexcept\r
-{\r
-    return static_cast<uint16> ((n << 8) | (n >> 8));\r
-}\r
-\r
 inline uint32 ByteOrder::swap (uint32 n) noexcept\r
 {\r
    #if JUCE_MAC || JUCE_IOS\r
@@ -174,66 +178,43 @@ inline uint64 ByteOrder::swap (uint64 value) noexcept
    #endif\r
 }\r
 \r
-#if JUCE_LITTLE_ENDIAN\r
- JUCE_CONSTEXPR inline uint16 ByteOrder::swapIfBigEndian (const uint16 v) noexcept                                  { return v; }\r
- inline uint32 ByteOrder::swapIfBigEndian (const uint32 v) noexcept                                                 { return v; }\r
- inline uint64 ByteOrder::swapIfBigEndian (const uint64 v) noexcept                                                 { return v; }\r
- JUCE_CONSTEXPR inline int16 ByteOrder::swapIfBigEndian (const int16 v) noexcept                                    { return v; }\r
- inline int32 ByteOrder::swapIfBigEndian (const int32 v) noexcept                                                   { return v; }\r
- inline int64 ByteOrder::swapIfBigEndian (const int64 v) noexcept                                                   { return v; }\r
- inline float ByteOrder::swapIfBigEndian (const float v) noexcept                                                   { return v; }\r
- inline double ByteOrder::swapIfBigEndian (const double v) noexcept                                                 { return v; }\r
-\r
- JUCE_CONSTEXPR inline uint16 ByteOrder::swapIfLittleEndian (const uint16 v) noexcept                               { return swap (v); }\r
- inline uint32 ByteOrder::swapIfLittleEndian (const uint32 v) noexcept                                              { return swap (v); }\r
- inline uint64 ByteOrder::swapIfLittleEndian (const uint64 v) noexcept                                              { return swap (v); }\r
- JUCE_CONSTEXPR inline int16 ByteOrder::swapIfLittleEndian (const int16 v) noexcept                                 { return static_cast<int16> (swap (static_cast<uint16> (v))); }\r
- inline int32 ByteOrder::swapIfLittleEndian (const int32 v) noexcept                                                { return static_cast<int32> (swap (static_cast<uint32> (v))); }\r
- inline int64 ByteOrder::swapIfLittleEndian (const int64 v) noexcept                                                { return static_cast<int64> (swap (static_cast<uint64> (v))); }\r
- inline float ByteOrder::swapIfLittleEndian (const float v) noexcept                                                { union { uint32 asUInt; float asFloat;  } n; n.asFloat = v; n.asUInt = ByteOrder::swap (n.asUInt); return n.asFloat; }\r
- inline double ByteOrder::swapIfLittleEndian (const double v) noexcept                                              { union { uint64 asUInt; double asFloat; } n; n.asFloat = v; n.asUInt = ByteOrder::swap (n.asUInt); return n.asFloat; }\r
-\r
- inline uint32 ByteOrder::littleEndianInt (const void* const bytes) noexcept                                        { return *static_cast<const uint32*> (bytes); }\r
- JUCE_CONSTEXPR inline uint32 ByteOrder::littleEndianInt (char c1, char c2, char c3, char c4) noexcept              { return (((uint32) c4) << 24) + (((uint32) c3) << 16) + (((uint32) c2) << 8) + (uint32) c1; }\r
-\r
- inline uint64 ByteOrder::littleEndianInt64 (const void* const bytes) noexcept                                      { return *static_cast<const uint64*> (bytes); }\r
- inline uint16 ByteOrder::littleEndianShort (const void* const bytes) noexcept                                      { return *static_cast<const uint16*> (bytes); }\r
- inline uint32 ByteOrder::bigEndianInt (const void* const bytes) noexcept                                           { return swap (*static_cast<const uint32*> (bytes)); }\r
- inline uint64 ByteOrder::bigEndianInt64 (const void* const bytes) noexcept                                         { return swap (*static_cast<const uint64*> (bytes)); }\r
- inline uint16 ByteOrder::bigEndianShort (const void* const bytes) noexcept                                         { return swap (*static_cast<const uint16*> (bytes)); }\r
- JUCE_CONSTEXPR inline bool ByteOrder::isBigEndian() noexcept                                                       { return false; }\r
-#else\r
- JUCE_CONSTEXPR inline uint16 ByteOrder::swapIfBigEndian (const uint16 v) noexcept                                  { return swap (v); }\r
- inline uint32 ByteOrder::swapIfBigEndian (const uint32 v) noexcept                                                 { return swap (v); }\r
- inline uint64 ByteOrder::swapIfBigEndian (const uint64 v) noexcept                                                 { return swap (v); }\r
- JUCE_CONSTEXPR inline int16 ByteOrder::swapIfBigEndian (const int16 v) noexcept                                    { return static_cast<int16> (swap (static_cast<uint16> (v))); }\r
- inline int32 ByteOrder::swapIfBigEndian (const int32 v) noexcept                                                   { return static_cast<int16> (swap (static_cast<uint16> (v))); }\r
- inline int64 ByteOrder::swapIfBigEndian (const int64 v) noexcept                                                   { return static_cast<int16> (swap (static_cast<uint16> (v))); }\r
- inline float ByteOrder::swapIfBigEndian (const float v) noexcept                                                   { union { uint32 asUInt; float asFloat;  } n; n.asFloat = v; n.asUInt = ByteOrder::swap (n.asUInt); return n.asFloat; }\r
- inline double ByteOrder::swapIfBigEndian (const double v) noexcept                                                 { union { uint64 asUInt; double asFloat; } n; n.asFloat = v; n.asUInt = ByteOrder::swap (n.asUInt); return n.asFloat; }\r
-\r
- JUCE_CONSTEXPR inline uint16 ByteOrder::swapIfLittleEndian (const uint16 v) noexcept                               { return v; }\r
- inline uint32 ByteOrder::swapIfLittleEndian (const uint32 v) noexcept                                              { return v; }\r
- inline uint64 ByteOrder::swapIfLittleEndian (const uint64 v) noexcept                                              { return v; }\r
- JUCE_CONSTEXPR inline int16 ByteOrder::swapIfLittleEndian (const int16 v) noexcept                                 { return v; }\r
- inline int32 ByteOrder::swapIfLittleEndian (const int32 v) noexcept                                                { return v; }\r
- inline int64 ByteOrder::swapIfLittleEndian (const int64 v) noexcept                                                { return v; }\r
- inline float ByteOrder::swapIfLittleEndian (const float v) noexcept                                                { return v; }\r
- inline double ByteOrder::swapIfLittleEndian (const double v) noexcept                                              { return v; }\r
-\r
- inline uint32 ByteOrder::littleEndianInt (const void* const bytes) noexcept                                        { return swap (*static_cast<const uint32*> (bytes)); }\r
- JUCE_CONSTEXPR inline uint32 ByteOrder::littleEndianInt (char c1, char c2, char c3, char c4) noexcept              { return (((uint32) c1) << 24) + (((uint32) c2) << 16) + (((uint32) c3) << 8) + (uint32) c4; }\r
- inline uint64 ByteOrder::littleEndianInt64 (const void* const bytes) noexcept                                      { return swap (*static_cast<const uint64*> (bytes)); }\r
- inline uint16 ByteOrder::littleEndianShort (const void* const bytes) noexcept                                      { return swap (*static_cast<const uint16*> (bytes)); }\r
- inline uint32 ByteOrder::bigEndianInt (const void* const bytes) noexcept                                           { return *static_cast<const uint32*> (bytes); }\r
- inline uint64 ByteOrder::bigEndianInt64 (const void* const bytes) noexcept                                         { return *static_cast<const uint64*> (bytes); }\r
- inline uint16 ByteOrder::bigEndianShort (const void* const bytes) noexcept                                         { return *static_cast<const uint16*> (bytes); }\r
- JUCE_CONSTEXPR inline bool ByteOrder::isBigEndian() noexcept                                                       { return true; }\r
-#endif\r
+JUCE_CONSTEXPR inline uint16 ByteOrder::makeInt (uint8 b0, uint8 b1) noexcept\r
+{\r
+    return static_cast<uint16> (static_cast<uint16> (b0) | (static_cast<uint16> (b1) << 8));\r
+}\r
+\r
+JUCE_CONSTEXPR inline uint32 ByteOrder::makeInt (uint8 b0, uint8 b1, uint8 b2, uint8 b3) noexcept\r
+{\r
+    return static_cast<uint32> (b0)        | (static_cast<uint32> (b1) << 8)\r
+        | (static_cast<uint32> (b2) << 16) | (static_cast<uint32> (b3) << 24);\r
+}\r
+\r
+JUCE_CONSTEXPR inline uint64 ByteOrder::makeInt (uint8 b0, uint8 b1, uint8 b2, uint8 b3, uint8 b4, uint8 b5, uint8 b6, uint8 b7) noexcept\r
+{\r
+    return static_cast<uint64> (b0)        | (static_cast<uint64> (b1) << 8)  | (static_cast<uint64> (b2) << 16) | (static_cast<uint64> (b3) << 24)\r
+        | (static_cast<uint64> (b4) << 32) | (static_cast<uint64> (b5) << 40) | (static_cast<uint64> (b6) << 48) | (static_cast<uint64> (b7) << 56);\r
+}\r
 \r
-inline int  ByteOrder::littleEndian24Bit (const void* const bytes) noexcept                                         { return (int) ((((unsigned int) static_cast<const int8*> (bytes)[2]) << 16) | (((unsigned int) static_cast<const uint8*> (bytes)[1]) << 8) | ((unsigned int) static_cast<const uint8*> (bytes)[0])); }\r
-inline int  ByteOrder::bigEndian24Bit (const void* const bytes) noexcept                                            { return (int) ((((unsigned int) static_cast<const int8*> (bytes)[0]) << 16) | (((unsigned int) static_cast<const uint8*> (bytes)[1]) << 8) | ((unsigned int) static_cast<const uint8*> (bytes)[2])); }\r
-inline void ByteOrder::littleEndian24BitToChars (const int value, void* const 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); }\r
-inline void ByteOrder::bigEndian24BitToChars (const int value, void* const 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; }\r
+JUCE_CONSTEXPR inline uint16 ByteOrder::littleEndianShort (const void* bytes) noexcept    { return makeInt (static_cast<const uint8*> (bytes)[0], static_cast<const uint8*> (bytes)[1]); }\r
+JUCE_CONSTEXPR inline uint32 ByteOrder::littleEndianInt   (const void* bytes) noexcept    { return makeInt (static_cast<const uint8*> (bytes)[0], static_cast<const uint8*> (bytes)[1],\r
+                                                                                                            static_cast<const uint8*> (bytes)[2], static_cast<const uint8*> (bytes)[3]); }\r
+JUCE_CONSTEXPR inline uint64 ByteOrder::littleEndianInt64 (const void* bytes) noexcept    { return makeInt (static_cast<const uint8*> (bytes)[0], static_cast<const uint8*> (bytes)[1],\r
+                                                                                                            static_cast<const uint8*> (bytes)[2], static_cast<const uint8*> (bytes)[3],\r
+                                                                                                            static_cast<const uint8*> (bytes)[4], static_cast<const uint8*> (bytes)[5],\r
+                                                                                                            static_cast<const uint8*> (bytes)[6], static_cast<const uint8*> (bytes)[7]); }\r
+\r
+JUCE_CONSTEXPR inline uint16 ByteOrder::bigEndianShort    (const void* bytes) noexcept    { return makeInt (static_cast<const uint8*> (bytes)[1], static_cast<const uint8*> (bytes)[0]); }\r
+JUCE_CONSTEXPR inline uint32 ByteOrder::bigEndianInt      (const void* bytes) noexcept    { return makeInt (static_cast<const uint8*> (bytes)[3], static_cast<const uint8*> (bytes)[2],\r
+                                                                                                            static_cast<const uint8*> (bytes)[1], static_cast<const uint8*> (bytes)[0]); }\r
+JUCE_CONSTEXPR inline uint64 ByteOrder::bigEndianInt64    (const void* bytes) noexcept    { return makeInt (static_cast<const uint8*> (bytes)[7], static_cast<const uint8*> (bytes)[6],\r
+                                                                                                            static_cast<const uint8*> (bytes)[5], static_cast<const uint8*> (bytes)[4],\r
+                                                                                                            static_cast<const uint8*> (bytes)[3], static_cast<const uint8*> (bytes)[2],\r
+                                                                                                            static_cast<const uint8*> (bytes)[1], static_cast<const uint8*> (bytes)[0]); }\r
+\r
+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])); }\r
+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])); }\r
+\r
+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); }\r
+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; }\r
 \r
 } // namespace juce\r
index a6299599c5e4fbafb58cf75c9d949f2e12142a63..eb2a50a3054c178c272653c0656e99377b0e3d87 100644 (file)
@@ -224,7 +224,10 @@ public class JuceAppActivity   extends $$JuceAppActivityBaseClass$$
 \r
         // Ensure that navigation/status bar visibility is correctly restored.\r
         for (int i = 0; i < viewHolder.getChildCount(); ++i)\r
-            ((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();\r
+        {\r
+            if (viewHolder.getChildAt (i) instanceof ComponentPeerView)\r
+                ((ComponentPeerView) viewHolder.getChildAt (i)).appResumed();\r
+        }\r
     }\r
 \r
     @Override\r
@@ -701,7 +704,7 @@ public class JuceAppActivity   extends $$JuceAppActivityBaseClass$$
         //==============================================================================\r
         private native void handleKeyDown (long host, int keycode, int textchar);\r
         private native void handleKeyUp (long host, int keycode, int textchar);\r
-        private native void handleBackButton (long host);
+        private native void handleBackButton (long host);\r
         private native void handleKeyboardHidden (long host);\r
 \r
         public void showKeyboard (String type)\r
@@ -713,12 +716,12 @@ public class JuceAppActivity   extends $$JuceAppActivityBaseClass$$
                 if (type.length() > 0)\r
                 {\r
                     imm.showSoftInput (this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT);\r
-                    imm.setInputMethod (getWindowToken(), type);
+                    imm.setInputMethod (getWindowToken(), type);\r
                     keyboardDismissListener.startListening();\r
                 }\r
                 else\r
                 {\r
-                    imm.hideSoftInputFromWindow (getWindowToken(), 0);
+                    imm.hideSoftInputFromWindow (getWindowToken(), 0);\r
                     keyboardDismissListener.stopListening();\r
                 }\r
             }\r
@@ -784,47 +787,65 @@ public class JuceAppActivity   extends $$JuceAppActivityBaseClass$$
             }\r
 \r
             return false;\r
-        }
-
-        //==============================================================================
-        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
-            {
-                @Override
-                public void onGlobalLayout()
-                {
-                    Rect r = new Rect();
-
-                    view.getWindowVisibleDisplayFrame(r);
-
-                    int diff = view.getHeight() - (r.bottom - r.top);
-
-                    // Arbitrary threshold, surely keyboard would take more than 20 pix.
-                    if (diff < 20)
-                        handleKeyboardHidden (view.host);
-                };
-            };
-
-            private ComponentPeerView view;
-            private TreeObserver viewTreeObserver = new TreeObserver();
-        }
-
+        }\r
+\r
+        //==============================================================================\r
+        private final class KeyboardDismissListener\r
+        {\r
+            public KeyboardDismissListener (ComponentPeerView viewToUse)\r
+            {\r
+                view = viewToUse;\r
+            }\r
+\r
+            private void startListening()\r
+            {\r
+                view.getViewTreeObserver().addOnGlobalLayoutListener(viewTreeObserver);\r
+            }\r
+\r
+            private void stopListening()\r
+            {\r
+                view.getViewTreeObserver().removeGlobalOnLayoutListener(viewTreeObserver);\r
+            }\r
+\r
+            private class TreeObserver implements ViewTreeObserver.OnGlobalLayoutListener\r
+            {\r
+                TreeObserver()\r
+                {\r
+                    keyboardShown = false;\r
+                }\r
+\r
+                @Override\r
+                public void onGlobalLayout()\r
+                {\r
+                    Rect r = new Rect();\r
+\r
+                    ViewGroup parentView = (ViewGroup) getParent();\r
+\r
+                    if (parentView == null)\r
+                        return;\r
+\r
+                    parentView.getWindowVisibleDisplayFrame (r);\r
+\r
+                    int diff = parentView.getHeight() - (r.bottom - r.top);\r
+\r
+                    // Arbitrary threshold, surely keyboard would take more than 20 pix.\r
+                    if (diff < 20 && keyboardShown)\r
+                    {\r
+                        keyboardShown = false;\r
+                        handleKeyboardHidden (view.host);\r
+                    }\r
+\r
+                    if (! keyboardShown && diff > 20)\r
+                        keyboardShown = true;\r
+                };\r
+\r
+                private boolean keyboardShown;\r
+            };\r
+\r
+            private ComponentPeerView view;\r
+            private TreeObserver viewTreeObserver = new TreeObserver();\r
+        }\r
+\r
         private KeyboardDismissListener keyboardDismissListener = new KeyboardDismissListener(this);\r
 \r
         // this is here to make keyboard entry work on a Galaxy Tab2 10.1\r
index 15f1c21b8ec3c84eaa539852bc9540511784374b..7ff4e625bc751be55f00a41a1af2fd1763e0f962 100644 (file)
  #include <shlobj.h>\r
  #include <shlwapi.h>\r
  #include <mmsystem.h>\r
+ #include <winioctl.h>\r
 \r
  #if JUCE_MINGW\r
   #include <basetyps.h>\r
index c22f64f77973d4e6d027d32ef4e084c0a4a4d590..d2d75e267c7216f6d2e863f14c93db1b95e45bfa 100644 (file)
@@ -55,26 +55,16 @@ bool File::isHidden() const
     return getFileName().startsWithChar ('.');\r
 }\r
 \r
-static String getLinkedFile (const String& file)\r
-{\r
-    HeapBlock<char> buffer (8194);\r
-    const int numBytes = (int) readlink (file.toRawUTF8(), buffer, 8192);\r
-    return String::fromUTF8 (buffer, jmax (0, numBytes));\r
-}\r
-\r
 bool File::isSymbolicLink() const\r
 {\r
-    return getLinkedFile (getFullPathName()).isNotEmpty();\r
+    return getNativeLinkedTarget().isNotEmpty();\r
 }\r
 \r
-File File::getLinkedTarget() const\r
+String File::getNativeLinkedTarget() const\r
 {\r
-    String f (getLinkedFile (getFullPathName()));\r
-\r
-    if (f.isNotEmpty())\r
-        return getSiblingFile (f);\r
-\r
-    return *this;\r
+    HeapBlock<char> buffer (8194);\r
+    const int numBytes = (int) readlink (getFullPathName().toRawUTF8(), buffer, 8192);\r
+    return String::fromUTF8 (buffer, jmax (0, numBytes));\r
 }\r
 \r
 //==============================================================================\r
index c95862bb857d2aad1a89c1b8fa2a66b713c52aee..c055621e033f1416b762f4b986f3a95ce54f53ae 100644 (file)
@@ -281,12 +281,12 @@ bool File::isSymbolicLink() const
     return getFileLink (fullPath) != nil;\r
 }\r
 \r
-File File::getLinkedTarget() const\r
+String File::getNativeLinkedTarget() const\r
 {\r
     if (NSString* dest = getFileLink (fullPath))\r
-        return getSiblingFile (nsStringToJuce (dest));\r
+        return nsStringToJuce (dest);\r
 \r
-    return *this;\r
+    return {};\r
 }\r
 \r
 //==============================================================================\r
index 4d16ae8facccd3122ec7f6ff8c5d84ba18d12d3e..3b94618003160dea60da6f4ca32925aa552321d9 100644 (file)
@@ -449,6 +449,9 @@ struct BackgroundDownloadTask  : public URL::DownloadTask
         if (session != nullptr)\r
             downloadTask = [session downloadTaskWithRequest:request];\r
 \r
+        // Workaround for an Apple bug. See https://github.com/AFNetworking/AFNetworking/issues/2334\r
+        [request HTTPBody];\r
+\r
         [request release];\r
     }\r
 \r
@@ -1118,6 +1121,9 @@ private:
                     [req addValue: juceStringToNS (value) forHTTPHeaderField: juceStringToNS (key)];\r
             }\r
 \r
+            // Workaround for an Apple bug. See https://github.com/AFNetworking/AFNetworking/issues/2334\r
+            [req HTTPBody];\r
+\r
             connection.reset (new URLConnectionState (req, numRedirectsToFollow));\r
         }\r
     }\r
index 7d4b91acf66fd64c3c1ac84404f81dff309333c9..1ca77c6b3b3fa211e178e776d313078618b2db91 100644 (file)
@@ -1127,20 +1127,19 @@ class ChildProcess::ActiveProcess
 {\r
 public:\r
     ActiveProcess (const StringArray& arguments, int streamFlags)\r
-        : childPID (0), pipeHandle (0), readHandle (0)\r
     {\r
-        String exe (arguments[0].unquoted());\r
+        auto exe = arguments[0].unquoted();\r
 \r
         // Looks like you're trying to launch a non-existent exe or a folder (perhaps on OSX\r
         // you're trying to launch the .app folder rather than the actual binary inside it?)\r
         jassert (File::getCurrentWorkingDirectory().getChildFile (exe).existsAsFile()\r
                   || ! exe.containsChar (File::getSeparatorChar()));\r
 \r
-        int pipeHandles[2] = { 0 };\r
+        int pipeHandles[2] = {};\r
 \r
         if (pipe (pipeHandles) == 0)\r
         {\r
-            const pid_t result = fork();\r
+            auto result = fork();\r
 \r
             if (result < 0)\r
             {\r
@@ -1165,9 +1164,10 @@ public:
                 close (pipeHandles[1]);\r
 \r
                 Array<char*> argv;\r
-                for (int i = 0; i < arguments.size(); ++i)\r
-                    if (arguments[i].isNotEmpty())\r
-                        argv.add (const_cast<char*> (arguments[i].toRawUTF8()));\r
+\r
+                for (auto& arg : arguments)\r
+                    if (arg.isNotEmpty())\r
+                        argv.add (const_cast<char*> (arg.toRawUTF8()));\r
 \r
                 argv.add (nullptr);\r
 \r
@@ -1186,7 +1186,7 @@ public:
 \r
     ~ActiveProcess()\r
     {\r
-        if (readHandle != 0)\r
+        if (readHandle != nullptr)\r
             fclose (readHandle);\r
 \r
         if (pipeHandle != 0)\r
@@ -1195,28 +1195,26 @@ public:
 \r
     bool isRunning() const noexcept\r
     {\r
-        if (childPID != 0)\r
-        {\r
-            int childState;\r
-            const int pid = waitpid (childPID, &childState, WNOHANG);\r
-            return pid == 0 || ! (WIFEXITED (childState) || WIFSIGNALED (childState));\r
-        }\r
+        if (childPID == 0)\r
+            return false;\r
 \r
-        return false;\r
+        int childState;\r
+        auto pid = waitpid (childPID, &childState, WNOHANG);\r
+        return pid == 0 || ! (WIFEXITED (childState) || WIFSIGNALED (childState));\r
     }\r
 \r
-    int read (void* const dest, const int numBytes) noexcept\r
+    int read (void* dest, int numBytes) noexcept\r
     {\r
-        jassert (dest != nullptr);\r
+        jassert (dest != nullptr && numBytes > 0);\r
 \r
         #ifdef fdopen\r
-         #error // the zlib headers define this function as NULL!\r
+         #error // some crazy 3rd party headers (e.g. zlib) define this function as NULL!\r
         #endif\r
 \r
-        if (readHandle == 0 && childPID != 0)\r
+        if (childPID != 0)\r
             readHandle = fdopen (pipeHandle, "r");\r
 \r
-        if (readHandle != 0)\r
+        if (readHandle != nullptr)\r
             return (int) fread (dest, 1, (size_t) numBytes, readHandle);\r
 \r
         return 0;\r
@@ -1232,7 +1230,7 @@ public:
         if (childPID != 0)\r
         {\r
             int childState = 0;\r
-            const int pid = waitpid (childPID, &childState, WNOHANG);\r
+            auto pid = waitpid (childPID, &childState, WNOHANG);\r
 \r
             if (pid >= 0 && WIFEXITED (childState))\r
                 return WEXITSTATUS (childState);\r
@@ -1241,11 +1239,9 @@ public:
         return 0;\r
     }\r
 \r
-    int childPID;\r
-\r
-private:\r
-    int pipeHandle;\r
-    FILE* readHandle;\r
+    int childPID = 0;\r
+    int pipeHandle = 0;\r
+    FILE* readHandle = {};\r
 \r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ActiveProcess)\r
 };\r
index b701d7f08c1c2c22eab593286aeb914ee4c78fd0..85e7f27a95ee2cc564cbc102d9201559e5032c1b 100644 (file)
@@ -30,6 +30,36 @@ namespace juce
 //==============================================================================\r
 namespace WindowsFileHelpers\r
 {\r
+    //==============================================================================\r
+   #if JUCE_WINDOWS\r
+    typedef struct _REPARSE_DATA_BUFFER {\r
+      ULONG  ReparseTag;\r
+      USHORT ReparseDataLength;\r
+      USHORT Reserved;\r
+      union {\r
+        struct {\r
+          USHORT SubstituteNameOffset;\r
+          USHORT SubstituteNameLength;\r
+          USHORT PrintNameOffset;\r
+          USHORT PrintNameLength;\r
+          ULONG  Flags;\r
+          WCHAR  PathBuffer[1];\r
+        } SymbolicLinkReparseBuffer;\r
+        struct {\r
+          USHORT SubstituteNameOffset;\r
+          USHORT SubstituteNameLength;\r
+          USHORT PrintNameOffset;\r
+          USHORT PrintNameLength;\r
+          WCHAR  PathBuffer[1];\r
+        } MountPointReparseBuffer;\r
+        struct {\r
+          UCHAR DataBuffer[1];\r
+        } GenericReparseBuffer;\r
+      } DUMMYUNIONNAME;\r
+    } *PREPARSE_DATA_BUFFER, REPARSE_DATA_BUFFER;\r
+   #endif\r
+\r
+    //==============================================================================\r
     DWORD getAtts (const String& path) noexcept\r
     {\r
         return GetFileAttributes (path.toWideCharPointer());\r
@@ -236,7 +266,8 @@ bool File::replaceInternal (const File& dest) const
     void* lpReserved = 0;\r
 \r
     return ReplaceFile (dest.getFullPathName().toWideCharPointer(), fullPath.toWideCharPointer(),\r
-                        0, REPLACEFILE_IGNORE_MERGE_ERRORS, lpExclude, lpReserved) != 0;\r
+                        0, REPLACEFILE_IGNORE_MERGE_ERRORS | REPLACEFILE_IGNORE_ACL_ERRORS,\r
+                        lpExclude, lpReserved) != 0;\r
 }\r
 \r
 Result File::createDirectoryInternal (const String& fileName) const\r
@@ -665,9 +696,104 @@ bool File::isShortcut() const
     return hasFileExtension (".lnk");\r
 }\r
 \r
-File File::getLinkedTarget() const\r
+static String readWindowsLnkFile (File lnkFile, bool wantsAbsolutePath)\r
+{\r
+    if (! lnkFile.exists())\r
+        lnkFile = File (lnkFile.getFullPathName() + ".lnk");\r
+\r
+    if (lnkFile.exists())\r
+    {\r
+        ComSmartPtr<IShellLink> shellLink;\r
+        ComSmartPtr<IPersistFile> persistFile;\r
+\r
+        if (SUCCEEDED (shellLink.CoCreateInstance (CLSID_ShellLink))\r
+             && SUCCEEDED (shellLink.QueryInterface (persistFile))\r
+             && SUCCEEDED (persistFile->Load (lnkFile.getFullPathName().toWideCharPointer(), STGM_READ))\r
+             && (! wantsAbsolutePath || SUCCEEDED (shellLink->Resolve (0, SLR_ANY_MATCH | SLR_NO_UI))))\r
+        {\r
+            WIN32_FIND_DATA winFindData;\r
+            WCHAR resolvedPath [MAX_PATH];\r
+\r
+            DWORD flags = SLGP_UNCPRIORITY;\r
+\r
+            if (! wantsAbsolutePath)\r
+                flags |= SLGP_RAWPATH;\r
+\r
+            if (SUCCEEDED (shellLink->GetPath (resolvedPath, MAX_PATH, &winFindData, flags)))\r
+                return resolvedPath;\r
+        }\r
+    }\r
+\r
+    return {};\r
+}\r
+\r
+static String readWindowsShortcutOrLink (const File& shortcut, bool wantsAbsolutePath)\r
 {\r
    #if JUCE_WINDOWS\r
+    if (! wantsAbsolutePath)\r
+    {\r
+        HANDLE h = CreateFile (shortcut.getFullPathName().toWideCharPointer(),\r
+                               GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,\r
+                               FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,\r
+                               0);\r
+\r
+        if (h != INVALID_HANDLE_VALUE)\r
+        {\r
+            HeapBlock<WindowsFileHelpers::REPARSE_DATA_BUFFER> reparseData;\r
+\r
+            reparseData.calloc (1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);\r
+            DWORD bytesReturned = 0;\r
+\r
+            bool success = DeviceIoControl (h, FSCTL_GET_REPARSE_POINT, nullptr, 0,\r
+                                            reparseData.getData(), MAXIMUM_REPARSE_DATA_BUFFER_SIZE,\r
+                                            &bytesReturned, nullptr) != 0;\r
+             CloseHandle (h);\r
+\r
+            if (success)\r
+            {\r
+                if (IsReparseTagMicrosoft (reparseData->ReparseTag))\r
+                {\r
+                    String targetPath;\r
+\r
+                    switch (reparseData->ReparseTag)\r
+                    {\r
+                        case IO_REPARSE_TAG_SYMLINK:\r
+                        {\r
+                            auto& symlinkData = reparseData->SymbolicLinkReparseBuffer;\r
+                            targetPath = {symlinkData.PathBuffer + (symlinkData.SubstituteNameOffset / sizeof (WCHAR)),\r
+                                          symlinkData.SubstituteNameLength / sizeof (WCHAR)};\r
+                        }\r
+                        break;\r
+\r
+                        case IO_REPARSE_TAG_MOUNT_POINT:\r
+                        {\r
+                            auto& mountData = reparseData->MountPointReparseBuffer;\r
+                            targetPath = {mountData.PathBuffer + (mountData.SubstituteNameOffset / sizeof (WCHAR)),\r
+                                          mountData.SubstituteNameLength / sizeof (WCHAR)};\r
+                        }\r
+                        break;\r
+\r
+                        default:\r
+                            break;\r
+                    }\r
+\r
+                    if (targetPath.isNotEmpty())\r
+                    {\r
+                        const StringRef prefix ("\\??\\");\r
+\r
+                        if (targetPath.startsWith (prefix))\r
+                            targetPath = targetPath.substring (prefix.length());\r
+\r
+                        return targetPath;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    if (! wantsAbsolutePath)\r
+        return readWindowsLnkFile (shortcut, false);\r
+\r
     typedef DWORD (WINAPI* GetFinalPathNameByHandleFunc) (HANDLE, LPTSTR, DWORD, DWORD);\r
 \r
     static GetFinalPathNameByHandleFunc getFinalPathNameByHandle\r
@@ -675,7 +801,7 @@ File File::getLinkedTarget() const
 \r
     if (getFinalPathNameByHandle != nullptr)\r
     {\r
-        HANDLE h = CreateFile (getFullPathName().toWideCharPointer(),\r
+        HANDLE h = CreateFile (shortcut.getFullPathName().toWideCharPointer(),\r
                                GENERIC_READ, FILE_SHARE_READ, nullptr,\r
                                OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);\r
 \r
@@ -694,8 +820,7 @@ File File::getLinkedTarget() const
 \r
                     // It turns out that GetFinalPathNameByHandleW prepends \\?\ to the path.\r
                     // This is not a bug, it's feature. See MSDN for more information.\r
-                    return File (path.startsWith (prefix) ? path.substring (prefix.length())\r
-                                                          : path);\r
+                    return path.startsWith (prefix) ? path.substring (prefix.length()) : path;\r
                 }\r
             }\r
 \r
@@ -704,30 +829,23 @@ File File::getLinkedTarget() const
     }\r
    #endif\r
 \r
-    File result (*this);\r
-    String p (getFullPathName());\r
-\r
-    if (! exists())\r
-        p += ".lnk";\r
-    else if (! hasFileExtension (".lnk"))\r
-        return result;\r
+    // as last resort try the resolve method of the ShellLink\r
+    return readWindowsLnkFile (shortcut, true);\r
+}\r
 \r
-    ComSmartPtr<IShellLink> shellLink;\r
-    ComSmartPtr<IPersistFile> persistFile;\r
+String File::getNativeLinkedTarget() const\r
+{\r
+    return readWindowsShortcutOrLink (*this, false);\r
+}\r
 \r
-    if (SUCCEEDED (shellLink.CoCreateInstance (CLSID_ShellLink))\r
-         && SUCCEEDED (shellLink.QueryInterface (persistFile))\r
-         && SUCCEEDED (persistFile->Load (p.toWideCharPointer(), STGM_READ))\r
-         && SUCCEEDED (shellLink->Resolve (0, SLR_ANY_MATCH | SLR_NO_UI)))\r
-    {\r
-        WIN32_FIND_DATA winFindData;\r
-        WCHAR resolvedPath [MAX_PATH];\r
+File File::getLinkedTarget() const\r
+{\r
+    auto target = readWindowsShortcutOrLink (*this, true);\r
 \r
-        if (SUCCEEDED (shellLink->GetPath (resolvedPath, MAX_PATH, &winFindData, SLGP_UNCPRIORITY)))\r
-            result = File (resolvedPath);\r
-    }\r
+    if (target.isNotEmpty() && File::isAbsolutePath (target))\r
+        return File (target);\r
 \r
-    return result;\r
+    return *this;\r
 }\r
 \r
 bool File::createShortcut (const String& description, const File& linkFileToCreate) const\r
index ffe913e2f836d0f27a9af4790a381d5e999d902a..d7bfe739aee7073742b163244ccfae5f618a3503 100644 (file)
@@ -28,6 +28,8 @@ namespace juce
     A type of InputSource that represents a URL.\r
 \r
     @see InputSource\r
+\r
+    @tags{Core}\r
 */\r
 class JUCE_API  URLInputSource     : public InputSource\r
 {\r
index 22cd0f39d0452dff0af98f498c47f3913cf7f9a8..f69a0541019071a1af3a16d8ae9849cc9260cded 100644 (file)
@@ -29,7 +29,7 @@
 */\r
 #define JUCE_MAJOR_VERSION      5\r
 #define JUCE_MINOR_VERSION      3\r
-#define JUCE_BUILDNUMBER        0\r
+#define JUCE_BUILDNUMBER        1\r
 \r
 /** Current JUCE version number.\r
 \r
index 2f6dba675dedc7f94661032e0f89248ec09bbde1..0b91231f021161de83518537429fafd6317dbac1 100644 (file)
@@ -207,13 +207,10 @@ void ThreadPool::moveJobToFront (const ThreadPoolJob* job) noexcept
 {\r
     const ScopedLock sl (lock);\r
 \r
-    if (! job->isActive)\r
-    {\r
-        auto index = jobs.indexOf (const_cast<ThreadPoolJob*> (job));\r
+    auto index = jobs.indexOf (const_cast<ThreadPoolJob*> (job));\r
 \r
-        if (index > 0)\r
-            jobs.move (index, 0);\r
-    }\r
+    if (index > 0 && ! job->isActive)\r
+        jobs.move (index, 0);\r
 }\r
 \r
 bool ThreadPool::waitForJobToFinish (const ThreadPoolJob* const job, const int timeOutMs) const\r
index b8afaf82b251e54b8251b8efc381bd9b9378ff2a..3e6a2fa9544e481ef8e8c6e206818ed18ea6f292 100644 (file)
@@ -439,6 +439,12 @@ XmlElement* XmlElement::getNextElementWithTagName (StringRef requiredTagName) co
     return e;\r
 }\r
 \r
+void XmlElement::setTagName (StringRef newTagName)\r
+{\r
+    jassert (isValidXmlName (newTagName));\r
+    tagName = StringPool::getGlobalPool().getPooledString (newTagName);\r
+}\r
+\r
 //==============================================================================\r
 int XmlElement::getNumAttributes() const noexcept\r
 {\r
index 22c497439b5e61225162999d6816aa6d4735cba1..91de12781dcfdd16f458b57d8160c425d4e05aa5 100644 (file)
@@ -278,6 +278,11 @@ public:
     */\r
     bool hasTagNameIgnoringNamespace (StringRef possibleTagName) const;\r
 \r
+    /** Changes this elements tag name.\r
+        @see getTagName\r
+     */\r
+    void setTagName (StringRef newTagName);\r
+\r
     //==============================================================================\r
     /** Returns the number of XML attributes this element contains.\r
 \r
index 933bf4360d59ae2eae1eefa04b5fd9d00a60c9da..19e96e5f42f63c8a846cb385a04d62988638449f 100644 (file)
@@ -46,6 +46,10 @@ struct ZipFile::ZipEntryHolder
         entry.uncompressedSize = (int64) readUnalignedLittleEndianInt (buffer + 24);\r
         streamOffset           = (int64) readUnalignedLittleEndianInt (buffer + 42);\r
 \r
+        auto externalFileAttributes = (int32) readUnalignedLittleEndianInt (buffer + 38);\r
+        auto fileType   = (externalFileAttributes >> 28) & 0xf;\r
+\r
+        entry.isSymbolicLink = (fileType == 0xA);\r
         entry.filename = String::fromUTF8 (buffer + 46, fileNameLen);\r
     }\r
 \r
@@ -430,6 +434,15 @@ Result ZipFile::uncompressEntry (int index, const File& targetDirectory, bool sh
     if (! targetFile.getParentDirectory().createDirectory())\r
         return Result::fail ("Failed to create target folder: " + targetFile.getParentDirectory().getFullPathName());\r
 \r
+    if (zei->entry.isSymbolicLink)\r
+    {\r
+        String originalFilePath (in->readEntireStreamAsString()\r
+                                    .replaceCharacter (L'/', File::getSeparatorChar()));\r
+\r
+        if (! File::createSymbolicLink (targetFile, originalFilePath, true))\r
+            return Result::fail ("Failed to create symbolic link: " + originalFilePath);\r
+    }\r
+    else\r
     {\r
         FileOutputStream out (targetFile);\r
 \r
@@ -453,13 +466,23 @@ struct ZipFile::Builder::Item
     Item (const File& f, InputStream* s, int compression, const String& storedPath, Time time)\r
         : file (f), stream (s), storedPathname (storedPath), fileTime (time), compressionLevel (compression)\r
     {\r
+        symbolicLink = (file.exists() && file.isSymbolicLink());\r
     }\r
 \r
     bool writeData (OutputStream& target, const int64 overallStartPosition)\r
     {\r
         MemoryOutputStream compressedData ((size_t) file.getSize());\r
 \r
-        if (compressionLevel > 0)\r
+        if (symbolicLink)\r
+        {\r
+            auto relativePath = file.getNativeLinkedTarget().replaceCharacter (File::getSeparatorChar(), L'/');\r
+\r
+            uncompressedSize = relativePath.length();\r
+\r
+            checksum = zlibNamespace::crc32 (0, (uint8_t*) relativePath.toRawUTF8(), (unsigned int) uncompressedSize);\r
+            compressedData << relativePath;\r
+        }\r
+        else if (compressionLevel > 0)\r
         {\r
             GZIPCompressorOutputStream compressor (compressedData, compressionLevel,\r
                                                    GZIPCompressorOutputStream::windowBitsRaw);\r
@@ -486,12 +509,12 @@ struct ZipFile::Builder::Item
     bool writeDirectoryEntry (OutputStream& target)\r
     {\r
         target.writeInt (0x02014b50);\r
-        target.writeShort (20); // version written\r
+        target.writeShort (symbolicLink ? 0x0314 : 0x0014);\r
         writeFlagsAndSizes (target);\r
         target.writeShort (0); // comment length\r
         target.writeShort (0); // start disk num\r
         target.writeShort (0); // internal attributes\r
-        target.writeInt (0); // external attributes\r
+        target.writeInt ((int) (symbolicLink ? 0xA1ED0000 : 0)); // external attributes\r
         target.writeInt ((int) (uint32) headerStart);\r
         target << storedPathname;\r
 \r
@@ -506,6 +529,7 @@ private:
     int64 compressedSize = 0, uncompressedSize = 0, headerStart = 0;\r
     int compressionLevel = 0;\r
     unsigned long checksum = 0;\r
+    bool symbolicLink = false;\r
 \r
     static void writeTimeAndDate (OutputStream& target, Time t)\r
     {\r
@@ -548,7 +572,7 @@ private:
     {\r
         target.writeShort (10); // version needed\r
         target.writeShort ((short) (1 << 11)); // this flag indicates UTF-8 filename encoding\r
-        target.writeShort (compressionLevel > 0 ? (short) 8 : (short) 0);\r
+        target.writeShort ((! symbolicLink && compressionLevel > 0) ? (short) 8 : (short) 0); //symlink target path is not compressed\r
         writeTimeAndDate (target, fileTime);\r
         target.writeInt ((int) checksum);\r
         target.writeInt ((int) (uint32) compressedSize);\r
index 0b4dcb8a885b396f4c04dc76ce782c95354fa20f..ffb210ed3b053c774fbf6131807ca30ddc8cc66a 100644 (file)
@@ -79,6 +79,9 @@ public:
 \r
         /** The last time the file was modified. */\r
         Time fileTime;\r
+\r
+        /** True if the zip entry is a symbolic link. */\r
+        bool isSymbolicLink;\r
     };\r
 \r
     //==============================================================================\r
index 9c9cccf965d4cb79b45eb70c3b23b619573d38b2..d6fb7562e580906014c3902a97eee3ffdf894d8b 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_cryptography\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE cryptography classes\r
   description:      Classes for various basic cryptography functions, including RSA, Blowfish, MD5, SHA, etc.\r
   website:          http://www.juce.com/juce\r
index 39102818683abedf94bddf7d96c7ae0350914ec7..6415f346767feecd58cb8b88347857f62ddf4219 100644 (file)
@@ -29,8 +29,8 @@ namespace juce
 \r
 namespace PropertyFileConstants\r
 {\r
-    JUCE_CONSTEXPR static const int magicNumber            = (int) ByteOrder::littleEndianInt ('P', 'R', 'O', 'P');\r
-    JUCE_CONSTEXPR static const int magicNumberCompressed  = (int) ByteOrder::littleEndianInt ('C', 'P', 'R', 'P');\r
+    JUCE_CONSTEXPR static const int magicNumber            = (int) ByteOrder::makeInt ('P', 'R', 'O', 'P');\r
+    JUCE_CONSTEXPR static const int magicNumberCompressed  = (int) ByteOrder::makeInt ('C', 'P', 'R', 'P');\r
 \r
     JUCE_CONSTEXPR static const char* const fileTag        = "PROPERTIES";\r
     JUCE_CONSTEXPR static const char* const valueTag       = "VALUE";\r
index 505164eb6612e2fe75f5f9e7ff3610bd79cbe800..7f5a199899760df470df7ef6c7d7cf36a3bce7e0 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_data_structures\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE data model helper classes\r
   description:      Classes for undo/redo management, and smart data structures.\r
   website:          http://www.juce.com/juce\r
index b85091297369216b39d4b3c20df9595dd818ecf5..dfdaed0a0553fc62bc8176857fff21c8fdcc4829 100644 (file)
@@ -98,7 +98,7 @@ void UndoManager::setMaxNumberOfStoredUnits (int maxUnits, int minTransactions)
 }\r
 \r
 //==============================================================================\r
-bool UndoManager::perform (UndoableAction* const newAction, const String& actionName)\r
+bool UndoManager::perform (UndoableAction* newAction, const String& actionName)\r
 {\r
     if (perform (newAction))\r
     {\r
@@ -237,8 +237,8 @@ String UndoManager::getCurrentTransactionName() const noexcept
 }\r
 \r
 //==============================================================================\r
-UndoManager::ActionSet* UndoManager::getCurrentSet() const noexcept     { return transactions [nextIndex - 1]; }\r
-UndoManager::ActionSet* UndoManager::getNextSet() const noexcept        { return transactions [nextIndex]; }\r
+UndoManager::ActionSet* UndoManager::getCurrentSet() const noexcept     { return transactions[nextIndex - 1]; }\r
+UndoManager::ActionSet* UndoManager::getNextSet() const noexcept        { return transactions[nextIndex]; }\r
 \r
 bool UndoManager::canUndo() const noexcept   { return getCurrentSet() != nullptr; }\r
 bool UndoManager::canRedo() const noexcept   { return getNextSet()    != nullptr; }\r
@@ -297,6 +297,32 @@ String UndoManager::getRedoDescription() const
     return {};\r
 }\r
 \r
+StringArray UndoManager::getUndoDescriptions() const\r
+{\r
+    StringArray descriptions;\r
+\r
+    for (int i = nextIndex;;)\r
+    {\r
+        if (auto* t = transactions[--i])\r
+            descriptions.add (t->name);\r
+        else\r
+            return descriptions;\r
+    }\r
+}\r
+\r
+StringArray UndoManager::getRedoDescriptions() const\r
+{\r
+    StringArray descriptions;\r
+\r
+    for (int i = nextIndex;;)\r
+    {\r
+        if (auto* t = transactions[i++])\r
+            descriptions.add (t->name);\r
+        else\r
+            return descriptions;\r
+    }\r
+}\r
+\r
 Time UndoManager::getTimeOfUndoTransaction() const\r
 {\r
     if (auto* s = getCurrentSet())\r
index 2edc5818721e5c7407732882527709fe076f75e4..3eac83abf680ad0c2d7e7a2c2101ae862cf5d9b7 100644 (file)
@@ -158,14 +158,10 @@ public:
     */\r
     bool canUndo() const noexcept;\r
 \r
-    /** Returns the name of the transaction that will be rolled-back when undo() is called.\r
-        @see undo\r
-    */\r
-    String getUndoDescription() const;\r
-\r
     /** Tries to roll-back the last transaction.\r
         @returns    true if the transaction can be undone, and false if it fails, or\r
                     if there aren't any transactions to undo\r
+        @see undoCurrentTransactionOnly\r
     */\r
     bool undo();\r
 \r
@@ -184,6 +180,23 @@ public:
     */\r
     bool undoCurrentTransactionOnly();\r
 \r
+    /** Returns the name of the transaction that will be rolled-back when undo() is called.\r
+        @see undo, canUndo, getUndoDescriptions\r
+    */\r
+    String getUndoDescription() const;\r
+\r
+    /** Returns the names of the sequence of transactions that will be performed if undo()\r
+        is repeatedly called. Note that for transactions where no name was provided, the\r
+        corresponding string will be empty.\r
+        @see undo, canUndo, getUndoDescription\r
+    */\r
+    StringArray getUndoDescriptions() const;\r
+\r
+    /** Returns the time to which the state would be restored if undo() was to be called.\r
+        If an undo isn't currently possible, it'll return Time().\r
+    */\r
+    Time getTimeOfUndoTransaction() const;\r
+\r
     /** Returns a list of the UndoableAction objects that have been performed during the\r
         transaction that is currently open.\r
 \r
@@ -200,33 +213,35 @@ public:
     */\r
     int getNumActionsInCurrentTransaction() const;\r
 \r
-    /** Returns the time to which the state would be restored if undo() was to be called.\r
-        If an undo isn't currently possible, it'll return Time().\r
-    */\r
-    Time getTimeOfUndoTransaction() const;\r
-\r
-    /** Returns the time to which the state would be restored if redo() was to be called.\r
-        If a redo isn't currently possible, it'll return Time::getCurrentTime().\r
-    */\r
-    Time getTimeOfRedoTransaction() const;\r
-\r
     //==============================================================================\r
     /** Returns true if there's at least one action in the list to redo.\r
         @see getRedoDescription, redo, canUndo\r
     */\r
     bool canRedo() const noexcept;\r
 \r
-    /** Returns the name of the transaction that will be redone when redo() is called.\r
-        @see redo\r
-    */\r
-    String getRedoDescription() const;\r
-\r
     /** Tries to redo the last transaction that was undone.\r
         @returns   true if the transaction can be redone, and false if it fails, or\r
                    if there aren't any transactions to redo\r
     */\r
     bool redo();\r
 \r
+    /** Returns the name of the transaction that will be redone when redo() is called.\r
+        @see redo, canRedo, getRedoDescriptions\r
+    */\r
+    String getRedoDescription() const;\r
+\r
+    /** Returns the names of the sequence of transactions that will be performed if redo()\r
+        is repeatedly called. Note that for transactions where no name was provided, the\r
+        corresponding string will be empty.\r
+        @see redo, canRedo, getRedoDescription\r
+    */\r
+    StringArray getRedoDescriptions() const;\r
+\r
+    /** Returns the time to which the state would be restored if redo() was to be called.\r
+        If a redo isn't currently possible, it'll return Time::getCurrentTime().\r
+        @see redo, canRedo\r
+    */\r
+    Time getTimeOfRedoTransaction() const;\r
 \r
 private:\r
     //==============================================================================\r
index 002f9a1d4b771f92ab11d19e34b8fa256de16131..211473ee783d22b6cf3ea8d927a2a9a1c0ab64bd 100644 (file)
@@ -44,8 +44,7 @@ public:
     ValueWithDefault()    : undoManager (nullptr) {}\r
 \r
     /** Creates an ValueWithDefault object. The default value will be an empty var. */\r
-    ValueWithDefault (ValueTree& tree, const Identifier& propertyID,\r
-                      UndoManager* um)\r
+    ValueWithDefault (ValueTree& tree, const Identifier& propertyID, UndoManager* um)\r
         : targetTree (tree),\r
           targetProperty (propertyID),\r
           undoManager (um),\r
@@ -54,8 +53,8 @@ public:
     }\r
 \r
     /** Creates an ValueWithDefault object. The default value will be defaultToUse. */\r
-    ValueWithDefault (ValueTree& tree, const Identifier& propertyID,\r
-                      UndoManager* um, const var& defaultToUse)\r
+    ValueWithDefault (ValueTree& tree, const Identifier& propertyID, UndoManager* um,\r
+                      const var& defaultToUse)\r
         : targetTree (tree),\r
           targetProperty (propertyID),\r
           undoManager (um),\r
@@ -63,12 +62,29 @@ public:
     {\r
     }\r
 \r
+    /** Creates an ValueWithDefault object. The default value will be defaultToUse.\r
+\r
+        Use this constructor if the underlying var object being controlled is an array and\r
+        it will handle the conversion to/from a delimited String that can be written to\r
+        XML format.\r
+    */\r
+    ValueWithDefault (ValueTree& tree, const Identifier& propertyID, UndoManager* um,\r
+                      const var& defaultToUse, StringRef arrayDelimiter)\r
+        : targetTree (tree),\r
+          targetProperty (propertyID),\r
+          undoManager (um),\r
+          defaultValue (defaultToUse),\r
+          delimiter (arrayDelimiter)\r
+    {\r
+    }\r
+\r
     /** Creates a ValueWithDefault object from another ValueWithDefault object. */\r
     ValueWithDefault (const ValueWithDefault& other)\r
         : targetTree (other.targetTree),\r
           targetProperty (other.targetProperty),\r
           undoManager (other.undoManager),\r
-          defaultValue (other.defaultValue)\r
+          defaultValue (other.defaultValue),\r
+          delimiter (other.delimiter)\r
     {\r
     }\r
 \r
@@ -81,6 +97,9 @@ public:
         if (isUsingDefault())\r
             return defaultValue;\r
 \r
+        if (delimiter.isNotEmpty())\r
+            return delimitedStringToVarArray (targetTree[targetProperty].toString());\r
+\r
         return targetTree[targetProperty];\r
     }\r
 \r
@@ -94,7 +113,12 @@ public:
     void setDefault (const var& newDefault)\r
     {\r
         if (defaultValue != newDefault)\r
+        {\r
             defaultValue = newDefault;\r
+\r
+            if (onDefaultChange != nullptr)\r
+                onDefaultChange();\r
+        }\r
     }\r
 \r
     /** Returns true if the property does not exist or is empty. */\r
@@ -109,6 +133,9 @@ public:
         targetTree.removeProperty (targetProperty, nullptr);\r
     }\r
 \r
+    /** You can assign a lambda to this callback object to have it called when the default value is changed. */\r
+    std::function<void()> onDefaultChange;\r
+\r
     //==============================================================================\r
     /** Sets the property and returns the new ValueWithDefault. This will modify the property in the referenced ValueTree. */\r
     ValueWithDefault& operator= (const var& newValue)\r
@@ -120,14 +147,17 @@ public:
     /** Sets the property. This will actually modify the property in the referenced ValueTree. */\r
     void setValue (const var& newValue, UndoManager* undoManagerToUse)\r
     {\r
-        targetTree.setProperty (targetProperty, newValue, undoManagerToUse);\r
+        if (auto* array = newValue.getArray())\r
+            targetTree.setProperty (targetProperty, varArrayToDelimitedString (*array), undoManagerToUse);\r
+        else\r
+            targetTree.setProperty (targetProperty, newValue, undoManagerToUse);\r
     }\r
 \r
     //==============================================================================\r
     /** Makes the ValueWithDefault refer to the specified property inside the given ValueTree. */\r
     void referTo (ValueTree& tree, const Identifier& property, UndoManager* um)\r
     {\r
-        referToWithDefault (tree, property, um, var());\r
+        referToWithDefault (tree, property, um, var(), {});\r
     }\r
 \r
     /** Makes the ValueWithDefault refer to the specified property inside the given ValueTree,\r
@@ -135,7 +165,13 @@ public:
      */\r
     void referTo (ValueTree& tree, const Identifier& property, UndoManager* um, const var& defaultVal)\r
     {\r
-        referToWithDefault (tree, property, um, defaultVal);\r
+        referToWithDefault (tree, property, um, defaultVal, {});\r
+    }\r
+\r
+    void referTo (ValueTree& tree, const Identifier& property, UndoManager* um,\r
+                  const var& defaultVal, StringRef arrayDelimiter)\r
+    {\r
+        referToWithDefault (tree, property, um, defaultVal, arrayDelimiter);\r
     }\r
 \r
     //==============================================================================\r
@@ -152,13 +188,41 @@ private:
     UndoManager* undoManager;\r
     var defaultValue;\r
 \r
+    String delimiter;\r
+\r
     //==============================================================================\r
-    void referToWithDefault (ValueTree& v, const Identifier& i, UndoManager* um, const var& defaultVal)\r
+    void referToWithDefault (ValueTree& v, const Identifier& i, UndoManager* um,\r
+                             const var& defaultVal, StringRef del)\r
     {\r
         targetTree = v;\r
         targetProperty = i;\r
         undoManager = um;\r
         defaultValue = defaultVal;\r
+        delimiter = del;\r
+    }\r
+\r
+    //==============================================================================\r
+    String varArrayToDelimitedString (const Array<var>& input) const noexcept\r
+    {\r
+        // if you are trying to control a var that is an array then you need to\r
+        // set a delimiter string that will be used when writing to XML!\r
+        jassert (delimiter.isNotEmpty());\r
+\r
+        StringArray elements;\r
+        for (auto& v : input)\r
+            elements.add (v.toString());\r
+\r
+        return elements.joinIntoString (delimiter);\r
+    }\r
+\r
+    Array<var> delimitedStringToVarArray (StringRef input) const noexcept\r
+    {\r
+        Array<var> arr;\r
+\r
+        for (auto t : StringArray::fromTokens (input, delimiter, {}))\r
+            arr.add (t);\r
+\r
+        return arr;\r
     }\r
 };\r
 \r
index f734c121cab9640d5bd9d3661559249ae9d54306..ea176799601e6f387e0bb2f74be495944a7b25ea 100644 (file)
@@ -166,10 +166,7 @@ struct FFTFallback  : public FFT::Instance
     void performRealOnlyForwardTransform (Complex<float>* scratch, float* d) const noexcept\r
     {\r
         for (int i = 0; i < size; ++i)\r
-        {\r
-            scratch[i].real (d[i]);\r
-            scratch[i].imag (0);\r
-        }\r
+            scratch[i] = { d[i], 0 };\r
 \r
         perform (scratch, reinterpret_cast<Complex<float>*> (d), false);\r
     }\r
@@ -204,8 +201,8 @@ struct FFTFallback  : public FFT::Instance
                 {\r
                     auto phase = i * inverseFactor;\r
 \r
-                    twiddleTable[i].real ((float) std::cos (phase));\r
-                    twiddleTable[i].imag ((float) std::sin (phase));\r
+                    twiddleTable[i] = { (float) std::cos (phase),\r
+                                        (float) std::sin (phase) };\r
                 }\r
             }\r
             else\r
@@ -214,16 +211,16 @@ struct FFTFallback  : public FFT::Instance
                 {\r
                     auto phase = i * inverseFactor;\r
 \r
-                    twiddleTable[i].real ((float) std::cos (phase));\r
-                    twiddleTable[i].imag ((float) std::sin (phase));\r
+                    twiddleTable[i] = { (float) std::cos (phase),\r
+                                        (float) std::sin (phase) };\r
                 }\r
 \r
                 for (int i = fftSize / 4; i < fftSize / 2; ++i)\r
                 {\r
-                    auto index = i - fftSize / 4;\r
+                    auto other = twiddleTable[i - fftSize / 4];\r
 \r
-                    twiddleTable[i].real (inverse ? -twiddleTable[index].imag() : twiddleTable[index].imag());\r
-                    twiddleTable[i].imag (inverse ? twiddleTable[index].real() : -twiddleTable[index].real());\r
+                    twiddleTable[i] = { inverse ? -other.imag() :  other.imag(),\r
+                                        inverse ?  other.real() : -other.real() };\r
                 }\r
 \r
                 twiddleTable[fftSize / 2].real (-1.0f);\r
@@ -395,17 +392,19 @@ struct FFTFallback  : public FFT::Instance
 \r
                 if (inverse)\r
                 {\r
-                    data[length].real (s5.real() - s4.imag());\r
-                    data[length].imag (s5.imag() + s4.real());\r
-                    data[lengthX3].real (s5.real() + s4.imag());\r
-                    data[lengthX3].imag (s5.imag() - s4.real());\r
+                    data[length] = { s5.real() - s4.imag(),\r
+                                     s5.imag() + s4.real() };\r
+\r
+                    data[lengthX3] = { s5.real() + s4.imag(),\r
+                                       s5.imag() - s4.real() };\r
                 }\r
                 else\r
                 {\r
-                    data[length].real (s5.real() + s4.imag());\r
-                    data[length].imag (s5.imag() - s4.real());\r
-                    data[lengthX3].real (s5.real() - s4.imag());\r
-                    data[lengthX3].imag (s5.imag() + s4.real());\r
+                    data[length] = { s5.real() + s4.imag(),\r
+                                     s5.imag() - s4.real() };\r
+\r
+                    data[lengthX3] = { s5.real() - s4.imag(),\r
+                                       s5.imag() + s4.real() };\r
                 }\r
 \r
                 ++data;\r
@@ -438,7 +437,7 @@ struct AppleFFT  : public FFT::Instance
     AppleFFT (int orderToUse)\r
         : order (static_cast<vDSP_Length> (orderToUse)),\r
           fftSetup (vDSP_create_fftsetup (order, 2)),\r
-          forwardNormalisation (.5f),\r
+          forwardNormalisation (0.5f),\r
           inverseNormalisation (1.0f / static_cast<float> (1 << order))\r
     {}\r
 \r
index 10da05144c6de00be4d59895614bef65e4d7aece..525e8e578fd7c341d8b1f8d20f9ecd1f2fb9325f 100644 (file)
@@ -58,7 +58,7 @@ public:
     /** Performs an out-of-place FFT, either forward or inverse.\r
         The arrays must contain at least getSize() elements.\r
     */\r
-    void perform (const Complex<float> *input, Complex<float> * output, bool inverse) const noexcept;\r
+    void perform (const Complex<float>* input, Complex<float>* output, bool inverse) const noexcept;\r
 \r
     /** Performs an in-place forward transform on a block of real data.\r
 \r
index 7cc6f406f90db77c7d52a985067f0945def55416..3cdd6c231c733f1a1a0e8e915ef217286642e2ba 100644 (file)
@@ -36,7 +36,7 @@
 \r
   ID:                 juce_dsp\r
   vendor:             juce\r
-  version:            5.3.0\r
+  version:            5.3.1\r
   name:               JUCE DSP classes\r
   description:        Classes for audio buffer manipulation, digital audio processing, filtering, oversampling, fast math functions etc.\r
   website:            http://www.juce.com/juce\r
@@ -198,15 +198,13 @@ namespace juce
 {\r
     namespace dsp\r
     {\r
-\r
         template <typename Type>\r
-        using Complex = ::std::complex<Type>;\r
+        using Complex = std::complex<Type>;\r
 \r
         //==============================================================================\r
         namespace util\r
         {\r
             /** Use this function to prevent denormals on intel CPUs.\r
-\r
                 This function will work with both primitives and simple containers.\r
             */\r
           #if JUCE_DSP_ENABLE_SNAP_TO_ZERO\r
index 4e480131121de49e42313c6797d4063f573025d6..03b7a31ff2c9d2c571097277d1dc833217897138 100644 (file)
@@ -120,9 +120,9 @@ Matrix<ElementType> Matrix<ElementType>::operator* (const Matrix<ElementType>& o
 \r
     size_t offsetMat = 0, offsetlhs = 0;\r
 \r
-    auto *dst = result.getRawDataPointer();\r
-    auto *a  = getRawDataPointer();\r
-    auto *b  = other.getRawDataPointer();\r
+    autodst = result.getRawDataPointer();\r
+    auto* a = getRawDataPointer();\r
+    auto* b = other.getRawDataPointer();\r
 \r
     for (size_t i = 0; i < n; ++i)\r
     {\r
index 657da301ae10fac88cf10c0ced4ae838b49579f9..b0f3817e80befddcc29ddcf22d242e328744361c 100644 (file)
@@ -465,18 +465,18 @@ private:
     /** This function calculates the equivalent high order IIR filter of a given\r
         polyphase cascaded allpass filters structure.\r
     */\r
-    const dsp::IIR::Coefficients<SampleType> getCoefficients (typename dsp::FilterDesign<SampleType>::IIRPolyphaseAllpassStructure &structure) const\r
+    const dsp::IIR::Coefficients<SampleType> getCoefficients (typename dsp::FilterDesign<SampleType>::IIRPolyphaseAllpassStructurestructure) const\r
     {\r
-        dsp::Polynomial<SampleType> numerator1 ({ static_cast<SampleType> (1.0) });\r
+        dsp::Polynomial<SampleType> numerator1   ({ static_cast<SampleType> (1.0) });\r
         dsp::Polynomial<SampleType> denominator1 ({ static_cast<SampleType> (1.0) });\r
-        dsp::Polynomial<SampleType> numerator2 ({ static_cast<SampleType> (1.0) });\r
+        dsp::Polynomial<SampleType> numerator2   ({ static_cast<SampleType> (1.0) });\r
         dsp::Polynomial<SampleType> denominator2 ({ static_cast<SampleType> (1.0) });\r
 \r
         dsp::Polynomial<SampleType> temp;\r
 \r
         for (auto n = 0; n < structure.directPath.size(); n++)\r
         {\r
-            auto *coeffs = structure.directPath.getReference (n).getRawCoefficients();\r
+            autocoeffs = structure.directPath.getReference (n).getRawCoefficients();\r
 \r
             if (structure.directPath[n].getFilterOrder() == 1)\r
             {\r
@@ -498,7 +498,7 @@ private:
 \r
         for (auto n = 0; n < structure.delayedPath.size(); n++)\r
         {\r
-            auto *coeffs = structure.delayedPath.getReference (n).getRawCoefficients();\r
+            autocoeffs = structure.delayedPath.getReference (n).getRawCoefficients();\r
 \r
             if (structure.delayedPath[n].getFilterOrder() == 1)\r
             {\r
@@ -520,7 +520,7 @@ private:
 \r
         dsp::Polynomial<SampleType> numeratorf1 = numerator1.getProductWith (denominator2);\r
         dsp::Polynomial<SampleType> numeratorf2 = numerator2.getProductWith (denominator1);\r
-        dsp::Polynomial<SampleType> numerator = numeratorf1.getSumWith (numeratorf2);\r
+        dsp::Polynomial<SampleType> numerator   = numeratorf1.getSumWith (numeratorf2);\r
         dsp::Polynomial<SampleType> denominator = denominator1.getProductWith (denominator2);\r
 \r
         dsp::IIR::Coefficients<SampleType> coeffs;\r
@@ -639,8 +639,7 @@ size_t Oversampling<SampleType>::getOversamplingFactor() noexcept
 template <typename SampleType>\r
 void Oversampling<SampleType>::initProcessing (size_t maximumNumberOfSamplesBeforeOversampling)\r
 {\r
-    jassert (engines.size() > 0);\r
-\r
+    jassert (! engines.isEmpty());\r
     auto currentNumSamples = maximumNumberOfSamplesBeforeOversampling;\r
 \r
     for (size_t n = 0; n < numStages; n++)\r
@@ -650,15 +649,15 @@ void Oversampling<SampleType>::initProcessing (size_t maximumNumberOfSamplesBefo
         engine.initProcessing (currentNumSamples);\r
         currentNumSamples *= engine.getFactor();\r
     }\r
-    isReady = true;\r
 \r
+    isReady = true;\r
     reset();\r
 }\r
 \r
 template <typename SampleType>\r
 void Oversampling<SampleType>::reset() noexcept\r
 {\r
-    jassert (engines.size() > 0);\r
+    jassert (! engines.isEmpty());\r
 \r
     if (isReady)\r
         for (auto n = 0; n < engines.size(); n++)\r
@@ -668,7 +667,7 @@ void Oversampling<SampleType>::reset() noexcept
 template <typename SampleType>\r
 typename dsp::AudioBlock<SampleType> Oversampling<SampleType>::processSamplesUp (const dsp::AudioBlock<SampleType> &inputBlock) noexcept\r
 {\r
-    jassert (engines.size() > 0);\r
+    jassert (! engines.isEmpty());\r
 \r
     if (! isReady)\r
         return dsp::AudioBlock<SampleType>();\r
@@ -688,7 +687,7 @@ typename dsp::AudioBlock<SampleType> Oversampling<SampleType>::processSamplesUp
 template <typename SampleType>\r
 void Oversampling<SampleType>::processSamplesDown (dsp::AudioBlock<SampleType> &outputBlock) noexcept\r
 {\r
-    jassert (engines.size() > 0);\r
+    jassert (! engines.isEmpty());\r
 \r
     if (! isReady)\r
         return;\r
index 1d36f7d5a4555ea2e23ea0cb2f5c8c2479dd037d..6af8b091c60021d4756d9bb9cec8be7d00062356 100644 (file)
@@ -31,7 +31,7 @@
 \r
   ID:               juce_events\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE message and event handling classes\r
   description:      Classes for running an application's main event loop and sending/receiving messages, timers, etc.\r
   website:          http://www.juce.com/juce\r
index 5792948ddd7032e8cf50e6786435dc3f15bcbd79..ba581757b660624da39f198c7afc1901608751f9 100644 (file)
@@ -794,7 +794,7 @@ public:
     */\r
     Rectangle transformedBy (const AffineTransform& transform) const noexcept\r
     {\r
-        typedef typename TypeHelpers::SmallestFloatType<ValueType>::type FloatType;\r
+        using FloatType = typename TypeHelpers::SmallestFloatType<ValueType>::type;\r
 \r
         auto x1 = static_cast<FloatType> (pos.x),     y1 = static_cast<FloatType> (pos.y);\r
         auto x2 = static_cast<FloatType> (pos.x + w), y2 = static_cast<FloatType> (pos.y);\r
@@ -816,7 +816,7 @@ public:
 \r
     /** Returns the smallest integer-aligned rectangle that completely contains this one.\r
         This is only relevant for floating-point rectangles, of course.\r
-        @see toFloat(), toNearestInt()\r
+        @see toFloat(), toNearestInt(), toNearestIntEdges()\r
     */\r
     Rectangle<int> getSmallestIntegerContainer() const noexcept\r
     {\r
@@ -829,7 +829,7 @@ public:
     /** Casts this rectangle to a Rectangle<int>.\r
         This uses roundToInt to snap x, y, width and height to the nearest integer (losing precision).\r
         If the rectangle already uses integers, this will simply return a copy.\r
-        @see getSmallestIntegerContainer()\r
+        @see getSmallestIntegerContainer(), toNearestIntEdges()\r
     */\r
     Rectangle<int> toNearestInt() const noexcept\r
     {\r
@@ -837,6 +837,17 @@ public:
                  roundToInt (w),     roundToInt (h) };\r
     }\r
 \r
+    /** Casts this rectangle to a Rectangle<int>.\r
+        This uses roundToInt to snap top, left, right and bottom to the nearest integer (losing precision).\r
+        If the rectangle already uses integers, this will simply return a copy.\r
+        @see getSmallestIntegerContainer(), toNearestInt()\r
+    */\r
+    Rectangle<int> toNearestIntEdges() const noexcept\r
+    {\r
+        return Rectangle<int>::leftTopRightBottom (roundToInt (pos.x),       roundToInt (pos.y),\r
+                                                   roundToInt (getRight()),  roundToInt (getBottom()));\r
+    }\r
+\r
     /** Casts this rectangle to a Rectangle<float>.\r
         @see getSmallestIntegerContainer\r
     */\r
index 85db587e0d5fc8fcf8f50ed293048fc45d698b3c..d52ec60cf0d83a282cdf99fbdfc667028c87fb9c 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_graphics\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE graphics classes\r
   description:      Classes for 2D vector graphics, image loading/saving, font handling, etc.\r
   website:          http://www.juce.com/juce\r
index d513657e956ca38833f49d899b465e83174be206..992dd414275b2ee27079ef44ed7e6172bc4f6077 100644 (file)
@@ -218,10 +218,12 @@ public:
     void getGlyphPositions (const String& text, Array<int>& glyphs, Array<float>& xOffsets) override\r
     {\r
         JNIEnv* env = getEnv();\r
-        const int numChars = text.length();\r
+        auto jtext = javaString (text);\r
+\r
+        const int numChars = env->GetStringLength (jtext.get());\r
         jfloatArray widths = env->NewFloatArray (numChars);\r
 \r
-        const int numDone = paint.callIntMethod (AndroidPaint.getTextWidths, javaString (text).get(), widths);\r
+        const int numDone = paint.callIntMethod (AndroidPaint.getTextWidths, jtext.get(), widths);\r
 \r
         HeapBlock<jfloat> localWidths (static_cast<size_t> (numDone));\r
         env->GetFloatArrayRegion (widths, 0, numDone, localWidths);\r
index 5b2ea2c63c5af311cc551a6eba7f83aba049e11b..99b3a0d871b21e6e2f8a1d9359e0ccef16b65403 100644 (file)
@@ -665,13 +665,8 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra
 \r
 bool CoreGraphicsContext::drawTextLayout (const AttributedString& text, const Rectangle<float>& area)\r
 {\r
-   #if JUCE_CORETEXT_AVAILABLE\r
     CoreTextTypeLayout::drawToCGContext (text, area, context, (float) flipHeight);\r
     return true;\r
-   #else\r
-    ignoreUnused (text, area);\r
-    return false;\r
-   #endif\r
 }\r
 \r
 CoreGraphicsContext::SavedState::SavedState()\r
index 21e595afeab528d7e87969ff2349680bf85bad57..92a5c143a75bf3061e8be57bc55b71a19f216032 100644 (file)
 namespace juce\r
 {\r
 \r
-#ifndef JUCE_CORETEXT_AVAILABLE\r
- #define JUCE_CORETEXT_AVAILABLE 1\r
-#endif\r
+static constexpr float referenceFontSize = 1024.0f;\r
 \r
-const float referenceFontSize = 1024.0f;\r
-\r
-#if JUCE_CORETEXT_AVAILABLE\r
-\r
-#if JUCE_MAC && MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5\r
-extern "C"\r
-{\r
-    void CTRunGetAdvances (CTRunRef, CFRange, CGSize buffer[]);\r
-    const CGSize* CTRunGetAdvancesPtr (CTRunRef);\r
-}\r
-#endif\r
-\r
-static CTFontRef getCTFontFromTypeface (const Font& f);\r
+static CTFontRef getCTFontFromTypeface (const Font&);\r
 \r
 namespace CoreTextTypeLayout\r
 {\r
     static String findBestAvailableStyle (const Font& font, CGAffineTransform& requiredTransform)\r
     {\r
-        const StringArray availableStyles (Font::findAllTypefaceStyles (font.getTypefaceName()));\r
-        const String style (font.getTypefaceStyle());\r
+        auto availableStyles = Font::findAllTypefaceStyles (font.getTypefaceName());\r
+        auto style = font.getTypefaceStyle();\r
 \r
         if (! availableStyles.contains (style))\r
         {\r
@@ -63,41 +49,10 @@ namespace CoreTextTypeLayout
         return style;\r
     }\r
 \r
-    // Workaround for Apple bug in CTFontCreateWithFontDescriptor in Garageband/Logic on 10.6\r
-   #if JUCE_MAC && ((! defined (MAC_OS_X_VERSION_10_7)) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7)\r
-    static CTFontRef getFontWithTrait (CTFontRef ctFontRef, CTFontSymbolicTraits trait)\r
-    {\r
-        if (CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits (ctFontRef, 0.0f, nullptr, trait, trait))\r
-        {\r
-            CFRelease (ctFontRef);\r
-            return newFont;\r
-        }\r
-\r
-        return ctFontRef;\r
-    }\r
-\r
-    static CTFontRef useStyleFallbackIfNecessary (CTFontRef ctFontRef, CFStringRef cfFontFamily,\r
-                                                  const float fontSizePoints, const Font& font)\r
-    {\r
-        CFStringRef cfActualFontFamily = (CFStringRef) CTFontCopyAttribute (ctFontRef, kCTFontFamilyNameAttribute);\r
-\r
-        if (CFStringCompare (cfFontFamily, cfActualFontFamily, 0) != kCFCompareEqualTo)\r
-        {\r
-            CFRelease (ctFontRef);\r
-            ctFontRef = CTFontCreateWithName (cfFontFamily, fontSizePoints, nullptr);\r
-\r
-            if (font.isItalic())   ctFontRef = getFontWithTrait (ctFontRef, kCTFontItalicTrait);\r
-            if (font.isBold())     ctFontRef = getFontWithTrait (ctFontRef, kCTFontBoldTrait);\r
-        }\r
-\r
-        CFRelease (cfActualFontFamily);\r
-        return ctFontRef;\r
-    }\r
-   #endif\r
-\r
     static float getFontTotalHeight (CTFontRef font)\r
     {\r
-        return std::abs ((float) CTFontGetAscent (font)) + std::abs ((float) CTFontGetDescent (font));\r
+        return std::abs ((float) CTFontGetAscent (font))\r
+             + std::abs ((float) CTFontGetDescent (font));\r
     }\r
 \r
     static float getHeightToPointsFactor (CTFontRef font)\r
@@ -107,35 +62,30 @@ namespace CoreTextTypeLayout
 \r
     static CTFontRef getFontWithPointSize (CTFontRef font, float size)\r
     {\r
-        CTFontRef newFont = CTFontCreateCopyWithAttributes (font, size, nullptr, nullptr);\r
+        auto newFont = CTFontCreateCopyWithAttributes (font, size, nullptr, nullptr);\r
         CFRelease (font);\r
         return newFont;\r
     }\r
 \r
     static CTFontRef createCTFont (const Font& font, const float fontSizePoints, CGAffineTransform& transformRequired)\r
     {\r
-        CFStringRef cfFontFamily = FontStyleHelpers::getConcreteFamilyName (font).toCFString();\r
-        CFStringRef cfFontStyle = findBestAvailableStyle (font, transformRequired).toCFString();\r
+        auto cfFontFamily = FontStyleHelpers::getConcreteFamilyName (font).toCFString();\r
+        auto cfFontStyle = findBestAvailableStyle (font, transformRequired).toCFString();\r
         CFStringRef keys[] = { kCTFontFamilyNameAttribute, kCTFontStyleNameAttribute };\r
         CFTypeRef values[] = { cfFontFamily, cfFontStyle };\r
 \r
-        CFDictionaryRef fontDescAttributes = CFDictionaryCreate (nullptr, (const void**) &keys,\r
-                                                                 (const void**) &values,\r
-                                                                 numElementsInArray (keys),\r
-                                                                 &kCFTypeDictionaryKeyCallBacks,\r
-                                                                 &kCFTypeDictionaryValueCallBacks);\r
+        auto fontDescAttributes = CFDictionaryCreate (nullptr, (const void**) &keys,\r
+                                                      (const void**) &values,\r
+                                                      numElementsInArray (keys),\r
+                                                      &kCFTypeDictionaryKeyCallBacks,\r
+                                                      &kCFTypeDictionaryValueCallBacks);\r
         CFRelease (cfFontStyle);\r
 \r
-        CTFontDescriptorRef ctFontDescRef = CTFontDescriptorCreateWithAttributes (fontDescAttributes);\r
+        auto ctFontDescRef = CTFontDescriptorCreateWithAttributes (fontDescAttributes);\r
         CFRelease (fontDescAttributes);\r
 \r
-        CTFontRef ctFontRef = CTFontCreateWithFontDescriptor (ctFontDescRef, fontSizePoints, nullptr);\r
+        auto ctFontRef = CTFontCreateWithFontDescriptor (ctFontDescRef, fontSizePoints, nullptr);\r
         CFRelease (ctFontDescRef);\r
-\r
-       #if JUCE_MAC && ((! defined (MAC_OS_X_VERSION_10_7)) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7)\r
-        ctFontRef = useStyleFallbackIfNecessary (ctFontRef, cfFontFamily, fontSizePoints, font);\r
-       #endif\r
-\r
         CFRelease (cfFontFamily);\r
 \r
         return ctFontRef;\r
@@ -144,8 +94,7 @@ namespace CoreTextTypeLayout
     //==============================================================================\r
     struct Advances\r
     {\r
-        Advances (CTRunRef run, const CFIndex numGlyphs)\r
-            : advances (CTRunGetAdvancesPtr (run))\r
+        Advances (CTRunRef run, CFIndex numGlyphs) : advances (CTRunGetAdvancesPtr (run))\r
         {\r
             if (advances == nullptr)\r
             {\r
@@ -161,8 +110,7 @@ namespace CoreTextTypeLayout
 \r
     struct Glyphs\r
     {\r
-        Glyphs (CTRunRef run, const size_t numGlyphs)\r
-            : glyphs (CTRunGetGlyphsPtr (run))\r
+        Glyphs (CTRunRef run, size_t numGlyphs) : glyphs (CTRunGetGlyphsPtr (run))\r
         {\r
             if (glyphs == nullptr)\r
             {\r
@@ -178,8 +126,7 @@ namespace CoreTextTypeLayout
 \r
     struct Positions\r
     {\r
-        Positions (CTRunRef run, const size_t numGlyphs)\r
-            : points (CTRunGetPositionsPtr (run))\r
+        Positions (CTRunRef run, size_t numGlyphs) : points (CTRunGetPositionsPtr (run))\r
         {\r
             if (points == nullptr)\r
             {\r
@@ -207,7 +154,7 @@ namespace CoreTextTypeLayout
 \r
     static CTFontRef getOrCreateFont (const Font& f)\r
     {\r
-        if (CTFontRef ctf = getCTFontFromTypeface (f))\r
+        if (auto ctf = getCTFontFromTypeface (f))\r
         {\r
             CFRetain (ctf);\r
             return ctf;\r
@@ -260,41 +207,39 @@ namespace CoreTextTypeLayout
     static CFAttributedStringRef createCFAttributedString (const AttributedString& text)\r
     {\r
        #if JUCE_IOS\r
-        CGColorSpaceRef rgbColourSpace = CGColorSpaceCreateDeviceRGB();\r
+        auto rgbColourSpace = CGColorSpaceCreateDeviceRGB();\r
        #endif\r
 \r
-        CFMutableAttributedStringRef attribString = CFAttributedStringCreateMutable (kCFAllocatorDefault, 0);\r
-\r
-        CFStringRef cfText = text.getText().toCFString();\r
+        auto attribString = CFAttributedStringCreateMutable (kCFAllocatorDefault, 0);\r
+        auto cfText = text.getText().toCFString();\r
         CFAttributedStringReplaceString (attribString, CFRangeMake (0, 0), cfText);\r
         CFRelease (cfText);\r
 \r
-        const int numCharacterAttributes = text.getNumAttributes();\r
-        const CFIndex attribStringLen = CFAttributedStringGetLength (attribString);\r
+        auto numCharacterAttributes = text.getNumAttributes();\r
+        auto attribStringLen = CFAttributedStringGetLength (attribString);\r
 \r
         for (int i = 0; i < numCharacterAttributes; ++i)\r
         {\r
-            const AttributedString::Attribute& attr = text.getAttribute (i);\r
-            const int rangeStart = attr.range.getStart();\r
+            auto& attr = text.getAttribute (i);\r
+            auto rangeStart = attr.range.getStart();\r
 \r
             if (rangeStart >= attribStringLen)\r
                 continue;\r
 \r
-            CFRange range = CFRangeMake (rangeStart, jmin (attr.range.getEnd(), (int) attribStringLen) - rangeStart);\r
+            auto range = CFRangeMake (rangeStart, jmin (attr.range.getEnd(), (int) attribStringLen) - rangeStart);\r
 \r
-            if (CTFontRef ctFontRef = getOrCreateFont (attr.font))\r
+            if (auto ctFontRef = getOrCreateFont (attr.font))\r
             {\r
                 ctFontRef = getFontWithPointSize (ctFontRef, attr.font.getHeight() * getHeightToPointsFactor (ctFontRef));\r
-\r
                 CFAttributedStringSetAttribute (attribString, range, kCTFontAttributeName, ctFontRef);\r
 \r
-                float extraKerning = attr.font.getExtraKerningFactor();\r
+                auto extraKerning = attr.font.getExtraKerningFactor();\r
 \r
-                if (extraKerning != 0.0f)\r
+                if (extraKerning != 0)\r
                 {\r
                     extraKerning *= attr.font.getHeight();\r
 \r
-                    CFNumberRef numberRef = CFNumberCreate (0, kCFNumberFloatType, &extraKerning);\r
+                    auto numberRef = CFNumberCreate (0, kCFNumberFloatType, &extraKerning);\r
                     CFAttributedStringSetAttribute (attribString, range, kCTKernAttributeName, numberRef);\r
                     CFRelease (numberRef);\r
                 }\r
@@ -303,19 +248,19 @@ namespace CoreTextTypeLayout
             }\r
 \r
             {\r
-                const Colour col (attr.colour);\r
+                auto col = attr.colour;\r
 \r
                #if JUCE_IOS\r
                 const CGFloat components[] = { col.getFloatRed(),\r
                                                col.getFloatGreen(),\r
                                                col.getFloatBlue(),\r
                                                col.getFloatAlpha() };\r
-                CGColorRef colour = CGColorCreate (rgbColourSpace, components);\r
+                auto colour = CGColorCreate (rgbColourSpace, components);\r
                #else\r
-                CGColorRef colour = CGColorCreateGenericRGB (col.getFloatRed(),\r
-                                                             col.getFloatGreen(),\r
-                                                             col.getFloatBlue(),\r
-                                                             col.getFloatAlpha());\r
+                auto colour = CGColorCreateGenericRGB (col.getFloatRed(),\r
+                                                       col.getFloatGreen(),\r
+                                                       col.getFloatBlue(),\r
+                                                       col.getFloatAlpha());\r
                #endif\r
 \r
                 CFAttributedStringSetAttribute (attribString, range, kCTForegroundColorAttributeName, colour);\r
@@ -324,25 +269,20 @@ namespace CoreTextTypeLayout
         }\r
 \r
         // Paragraph Attributes\r
-        CTTextAlignment ctTextAlignment = getTextAlignment (text);\r
-        CTLineBreakMode ctLineBreakMode = getLineBreakMode (text);\r
-        CTWritingDirection ctWritingDirection = getWritingDirection (text);\r
-        const CGFloat ctLineSpacing = text.getLineSpacing();\r
+        auto ctTextAlignment = getTextAlignment (text);\r
+        auto ctLineBreakMode = getLineBreakMode (text);\r
+        auto ctWritingDirection = getWritingDirection (text);\r
+        CGFloat ctLineSpacing = text.getLineSpacing();\r
 \r
         CTParagraphStyleSetting settings[] =\r
         {\r
             { kCTParagraphStyleSpecifierAlignment,              sizeof (CTTextAlignment), &ctTextAlignment },\r
             { kCTParagraphStyleSpecifierLineBreakMode,          sizeof (CTLineBreakMode), &ctLineBreakMode },\r
             { kCTParagraphStyleSpecifierBaseWritingDirection,   sizeof (CTWritingDirection), &ctWritingDirection},\r
-\r
-           #if defined (MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7\r
             { kCTParagraphStyleSpecifierLineSpacingAdjustment,  sizeof (CGFloat),         &ctLineSpacing }\r
-           #else\r
-            { kCTParagraphStyleSpecifierLineSpacing,            sizeof (CGFloat),         &ctLineSpacing }\r
-           #endif\r
         };\r
 \r
-        CTParagraphStyleRef ctParagraphStyleRef = CTParagraphStyleCreate (settings, (size_t) numElementsInArray (settings));\r
+        auto ctParagraphStyleRef = CTParagraphStyleCreate (settings, (size_t) numElementsInArray (settings));\r
         CFAttributedStringSetAttribute (attribString, CFRangeMake (0, CFAttributedStringGetLength (attribString)),\r
                                         kCTParagraphStyleAttributeName, ctParagraphStyleRef);\r
         CFRelease (ctParagraphStyleRef);\r
@@ -354,14 +294,14 @@ namespace CoreTextTypeLayout
 \r
     static CTFrameRef createCTFrame (const AttributedString& text, CGRect bounds)\r
     {\r
-        CFAttributedStringRef attribString = createCFAttributedString (text);\r
-        CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString (attribString);\r
+        auto attribString = createCFAttributedString (text);\r
+        auto framesetter = CTFramesetterCreateWithAttributedString (attribString);\r
         CFRelease (attribString);\r
 \r
-        CGMutablePathRef path = CGPathCreateMutable();\r
+        auto path = CGPathCreateMutable();\r
         CGPathAddRect (path, nullptr, bounds);\r
 \r
-        CTFrameRef frame = CTFramesetterCreateFrame (framesetter, CFRangeMake (0, 0), path, nullptr);\r
+        auto frame = CTFramesetterCreateFrame (framesetter, CFRangeMake (0, 0), path, nullptr);\r
         CFRelease (framesetter);\r
         CGPathRelease (path);\r
 \r
@@ -371,19 +311,20 @@ namespace CoreTextTypeLayout
     static Range<float> getLineVerticalRange (CTFrameRef frame, CFArrayRef lines, int lineIndex)\r
     {\r
         LineInfo info (frame, (CTLineRef) CFArrayGetValueAtIndex (lines, lineIndex), lineIndex);\r
-        return Range<float> ((float) (info.origin.y - info.descent),\r
-                             (float) (info.origin.y + info.ascent));\r
+\r
+        return { (float) (info.origin.y - info.descent),\r
+                 (float) (info.origin.y + info.ascent) };\r
     }\r
 \r
     static float findCTFrameHeight (CTFrameRef frame)\r
     {\r
-        CFArrayRef lines = CTFrameGetLines (frame);\r
-        const CFIndex numLines = CFArrayGetCount (lines);\r
+        auto lines = CTFrameGetLines (frame);\r
+        auto numLines = CFArrayGetCount (lines);\r
 \r
         if (numLines == 0)\r
             return 0;\r
 \r
-        Range<float> range (getLineVerticalRange (frame, lines, 0));\r
+        auto range = getLineVerticalRange (frame, lines, 0);\r
 \r
         if (numLines > 1)\r
             range = range.getUnionWith (getLineVerticalRange (frame, lines, (int) numLines - 1));\r
@@ -392,11 +333,10 @@ namespace CoreTextTypeLayout
     }\r
 \r
     static void drawToCGContext (const AttributedString& text, const Rectangle<float>& area,\r
-                                 const CGContextRef& context, const float flipHeight)\r
+                                 const CGContextRef& context, float flipHeight)\r
     {\r
         Rectangle<float> ctFrameArea;\r
-\r
-        const int verticalJustification = text.getJustification().getOnlyVerticalFlags();\r
+        auto verticalJustification = text.getJustification().getOnlyVerticalFlags();\r
 \r
         // Ugly hack to fix a bug in OS X Sierra where the CTFrame needs to be slightly\r
         // larger than the font height - otherwise the CTFrame will be invalid\r
@@ -407,13 +347,13 @@ namespace CoreTextTypeLayout
         else\r
             ctFrameArea = area.withHeight (area.getHeight() * 1.1f);\r
 \r
-        CTFrameRef frame = createCTFrame (text, CGRectMake ((CGFloat) ctFrameArea.getX(), flipHeight - (CGFloat) ctFrameArea.getBottom(),\r
-                                                            (CGFloat) ctFrameArea.getWidth(), (CGFloat) ctFrameArea.getHeight()));\r
+        auto frame = createCTFrame (text, CGRectMake ((CGFloat) ctFrameArea.getX(), flipHeight - (CGFloat) ctFrameArea.getBottom(),\r
+                                                      (CGFloat) ctFrameArea.getWidth(), (CGFloat) ctFrameArea.getHeight()));\r
 \r
         if (verticalJustification == Justification::verticallyCentred\r
              || verticalJustification == Justification::bottom)\r
         {\r
-            float adjust = ctFrameArea.getHeight() - findCTFrameHeight (frame);\r
+            auto adjust = ctFrameArea.getHeight() - findCTFrameHeight (frame);\r
 \r
             if (verticalJustification == Justification::verticallyCentred)\r
                 adjust *= 0.5f;\r
@@ -433,45 +373,43 @@ namespace CoreTextTypeLayout
 \r
     static void createLayout (TextLayout& glyphLayout, const AttributedString& text)\r
     {\r
-        const CGFloat boundsHeight = glyphLayout.getHeight();\r
-        CTFrameRef frame = createCTFrame (text, CGRectMake (0, 0, glyphLayout.getWidth(), boundsHeight));\r
-\r
-        CFArrayRef lines = CTFrameGetLines (frame);\r
-        const CFIndex numLines = CFArrayGetCount (lines);\r
+        auto boundsHeight = glyphLayout.getHeight();\r
+        auto frame = createCTFrame (text, CGRectMake (0, 0, glyphLayout.getWidth(), boundsHeight));\r
+        auto lines = CTFrameGetLines (frame);\r
+        auto numLines = CFArrayGetCount (lines);\r
 \r
         glyphLayout.ensureStorageAllocated ((int) numLines);\r
 \r
         for (CFIndex i = 0; i < numLines; ++i)\r
         {\r
-            CTLineRef line = (CTLineRef) CFArrayGetValueAtIndex (lines, i);\r
-\r
-            CFArrayRef runs = CTLineGetGlyphRuns (line);\r
-            const CFIndex numRuns = CFArrayGetCount (runs);\r
+            auto line = (CTLineRef) CFArrayGetValueAtIndex (lines, i);\r
+            auto runs = CTLineGetGlyphRuns (line);\r
+            auto numRuns = CFArrayGetCount (runs);\r
 \r
-            const CFRange cfrlineStringRange = CTLineGetStringRange (line);\r
-            const CFIndex lineStringEnd = cfrlineStringRange.location + cfrlineStringRange.length - 1;\r
-            const Range<int> lineStringRange ((int) cfrlineStringRange.location, (int) lineStringEnd);\r
+            auto cfrlineStringRange = CTLineGetStringRange (line);\r
+            auto lineStringEnd = cfrlineStringRange.location + cfrlineStringRange.length - 1;\r
+            Range<int> lineStringRange ((int) cfrlineStringRange.location, (int) lineStringEnd);\r
 \r
             LineInfo lineInfo (frame, line, i);\r
 \r
-            TextLayout::Line* const glyphLine = new TextLayout::Line (lineStringRange,\r
-                                                                      Point<float> ((float) lineInfo.origin.x,\r
-                                                                                    (float) (boundsHeight - lineInfo.origin.y)),\r
-                                                                      (float) lineInfo.ascent,\r
-                                                                      (float) lineInfo.descent,\r
-                                                                      (float) lineInfo.leading,\r
-                                                                      (int) numRuns);\r
+            auto glyphLine = new TextLayout::Line (lineStringRange,\r
+                                                   Point<float> ((float) lineInfo.origin.x,\r
+                                                                 (float) (boundsHeight - lineInfo.origin.y)),\r
+                                                   (float) lineInfo.ascent,\r
+                                                   (float) lineInfo.descent,\r
+                                                   (float) lineInfo.leading,\r
+                                                   (int) numRuns);\r
             glyphLayout.addLine (glyphLine);\r
 \r
             for (CFIndex j = 0; j < numRuns; ++j)\r
             {\r
-                CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (runs, j);\r
-                const CFIndex numGlyphs = CTRunGetGlyphCount (run);\r
-                const CFRange runStringRange = CTRunGetStringRange (run);\r
+                auto run = (CTRunRef) CFArrayGetValueAtIndex (runs, j);\r
+                auto numGlyphs = CTRunGetGlyphCount (run);\r
+                auto runStringRange = CTRunGetStringRange (run);\r
 \r
-                TextLayout::Run* const glyphRun = new TextLayout::Run (Range<int> ((int) runStringRange.location,\r
-                                                                                   (int) (runStringRange.location + runStringRange.length - 1)),\r
-                                                                       (int) numGlyphs);\r
+                auto glyphRun = new TextLayout::Run (Range<int> ((int) runStringRange.location,\r
+                                                                 (int) (runStringRange.location + runStringRange.length - 1)),\r
+                                                     (int) numGlyphs);\r
                 glyphLine->runs.add (glyphRun);\r
 \r
                 CFDictionaryRef runAttributes = CTRunGetAttributes (run);\r
@@ -479,15 +417,15 @@ namespace CoreTextTypeLayout
                 CTFontRef ctRunFont;\r
                 if (CFDictionaryGetValueIfPresent (runAttributes, kCTFontAttributeName, (const void**) &ctRunFont))\r
                 {\r
-                    CFStringRef cfsFontName = CTFontCopyPostScriptName (ctRunFont);\r
-                    CTFontRef ctFontRef = CTFontCreateWithName (cfsFontName, referenceFontSize, nullptr);\r
+                    auto cfsFontName = CTFontCopyPostScriptName (ctRunFont);\r
+                    auto ctFontRef = CTFontCreateWithName (cfsFontName, referenceFontSize, nullptr);\r
                     CFRelease (cfsFontName);\r
 \r
-                    const float fontHeightToPointsFactor = getHeightToPointsFactor (ctFontRef);\r
+                    auto fontHeightToPointsFactor = getHeightToPointsFactor (ctFontRef);\r
                     CFRelease (ctFontRef);\r
 \r
-                    CFStringRef cfsFontFamily = (CFStringRef) CTFontCopyAttribute (ctRunFont, kCTFontFamilyNameAttribute);\r
-                    CFStringRef cfsFontStyle  = (CFStringRef) CTFontCopyAttribute (ctRunFont, kCTFontStyleNameAttribute);\r
+                    auto cfsFontFamily = (CFStringRef) CTFontCopyAttribute (ctRunFont, kCTFontFamilyNameAttribute);\r
+                    auto cfsFontStyle  = (CFStringRef) CTFontCopyAttribute (ctRunFont, kCTFontStyleNameAttribute);\r
 \r
                     glyphRun->font = Font (String::fromCFString (cfsFontFamily),\r
                                            String::fromCFString (cfsFontStyle),\r
@@ -498,10 +436,11 @@ namespace CoreTextTypeLayout
                 }\r
 \r
                 CGColorRef cgRunColor;\r
+\r
                 if (CFDictionaryGetValueIfPresent (runAttributes, kCTForegroundColorAttributeName, (const void**) &cgRunColor)\r
                      && CGColorGetNumberOfComponents (cgRunColor) == 4)\r
                 {\r
-                    const CGFloat* const components = CGColorGetComponents (cgRunColor);\r
+                    auto* components = CGColorGetComponents (cgRunColor);\r
 \r
                     glyphRun->colour = Colour::fromFloatRGBA ((float) components[0],\r
                                                               (float) components[1],\r
@@ -530,16 +469,7 @@ class OSXTypeface  : public Typeface
 {\r
 public:\r
     OSXTypeface (const Font& font)\r
-        : Typeface (font.getTypefaceName(),\r
-                    font.getTypefaceStyle()),\r
-          fontRef (nullptr),\r
-          ctFontRef (nullptr),\r
-          fontHeightToPointsFactor (1.0f),\r
-          renderingTransform (CGAffineTransformIdentity),\r
-          isMemoryFont (false),\r
-          attributedStringAtts (nullptr),\r
-          ascent (0.0f),\r
-          unitsToHeightScaleFactor (0.0f)\r
+        : Typeface (font.getTypefaceName(), font.getTypefaceStyle()), isMemoryFont (false)\r
     {\r
         ctFontRef = CoreTextTypeLayout::createCTFont (font, referenceFontSize, renderingTransform);\r
 \r
@@ -551,22 +481,13 @@ public:
     }\r
 \r
     OSXTypeface (const void* data, size_t dataSize)\r
-        : Typeface (String(), String()),\r
-          fontRef (nullptr),\r
-          ctFontRef (nullptr),\r
-          fontHeightToPointsFactor (1.0f),\r
-          renderingTransform (CGAffineTransformIdentity),\r
-          isMemoryFont (true),\r
-          dataCopy (data, dataSize),\r
-          attributedStringAtts (nullptr),\r
-          ascent (0.0f),\r
-          unitsToHeightScaleFactor (0.0f)\r
+        : Typeface ({}, {}), isMemoryFont (true), dataCopy (data, dataSize)\r
     {\r
         // We can't use CFDataCreate here as this triggers a false positive in ASAN\r
         // so copy the data manually and use CFDataCreateWithBytesNoCopy\r
-        CFDataRef cfData = CFDataCreateWithBytesNoCopy (kCFAllocatorDefault, (const UInt8*) dataCopy.getData(),\r
-                                                        (CFIndex) dataCopy.getSize(), kCFAllocatorNull);\r
-        CGDataProviderRef provider = CGDataProviderCreateWithCFData (cfData);\r
+        auto cfData = CFDataCreateWithBytesNoCopy (kCFAllocatorDefault, (const UInt8*) dataCopy.getData(),\r
+                                                   (CFIndex) dataCopy.getSize(), kCFAllocatorNull);\r
+        auto provider = CGDataProviderCreateWithCFData (cfData);\r
         CFRelease (cfData);\r
 \r
        #if JUCE_IOS\r
@@ -585,13 +506,13 @@ public:
 \r
             if (ctFontRef != nullptr)\r
             {\r
-                if (CFStringRef fontName = CTFontCopyName (ctFontRef, kCTFontFamilyNameKey))\r
+                if (auto fontName = CTFontCopyName (ctFontRef, kCTFontFamilyNameKey))\r
                 {\r
                     name = String::fromCFString (fontName);\r
                     CFRelease (fontName);\r
                 }\r
 \r
-                if (CFStringRef fontStyle = CTFontCopyName (ctFontRef, kCTFontStyleNameKey))\r
+                if (auto fontStyle = CTFontCopyName (ctFontRef, kCTFontStyleNameKey))\r
                 {\r
                     style = String::fromCFString (fontStyle);\r
                     CFRelease (fontStyle);\r
@@ -604,9 +525,9 @@ public:
 \r
     void initialiseMetrics()\r
     {\r
-        const float ctAscent  = std::abs ((float) CTFontGetAscent (ctFontRef));\r
-        const float ctDescent = std::abs ((float) CTFontGetDescent (ctFontRef));\r
-        const float ctTotalHeight = ctAscent + ctDescent;\r
+        auto ctAscent  = std::abs ((float) CTFontGetAscent (ctFontRef));\r
+        auto ctDescent = std::abs ((float) CTFontGetDescent (ctFontRef));\r
+        auto ctTotalHeight = ctAscent + ctDescent;\r
 \r
         ascent = ctAscent / ctTotalHeight;\r
         unitsToHeightScaleFactor = 1.0f / ctTotalHeight;\r
@@ -615,7 +536,7 @@ public:
         fontHeightToPointsFactor = referenceFontSize / ctTotalHeight;\r
 \r
         const short zero = 0;\r
-        CFNumberRef numberRef = CFNumberCreate (0, kCFNumberShortType, &zero);\r
+        auto numberRef = CFNumberCreate (0, kCFNumberShortType, &zero);\r
 \r
         CFStringRef keys[] = { kCTFontAttributeName, kCTLigatureAttributeName };\r
         CFTypeRef values[] = { ctFontRef, numberRef };\r
@@ -626,14 +547,9 @@ public:
 \r
     ~OSXTypeface()\r
     {\r
-        if (attributedStringAtts != nullptr)\r
-            CFRelease (attributedStringAtts);\r
-\r
-        if (fontRef != nullptr)\r
-            CGFontRelease (fontRef);\r
-\r
-        if (ctFontRef != nullptr)\r
-            CFRelease (ctFontRef);\r
+        if (attributedStringAtts != nullptr)    CFRelease (attributedStringAtts);\r
+        if (fontRef != nullptr)                 CGFontRelease (fontRef);\r
+        if (ctFontRef != nullptr)               CFRelease (ctFontRef);\r
     }\r
 \r
     float getAscent() const override                 { return ascent; }\r
@@ -646,17 +562,17 @@ public:
 \r
         if (ctFontRef != nullptr && text.isNotEmpty())\r
         {\r
-            CFStringRef cfText = text.toCFString();\r
-            CFAttributedStringRef attribString = CFAttributedStringCreate (kCFAllocatorDefault, cfText, attributedStringAtts);\r
+            auto cfText = text.toCFString();\r
+            auto attribString = CFAttributedStringCreate (kCFAllocatorDefault, cfText, attributedStringAtts);\r
             CFRelease (cfText);\r
 \r
-            CTLineRef line = CTLineCreateWithAttributedString (attribString);\r
-            CFArrayRef runArray = CTLineGetGlyphRuns (line);\r
+            auto line = CTLineCreateWithAttributedString (attribString);\r
+            auto runArray = CTLineGetGlyphRuns (line);\r
 \r
             for (CFIndex i = 0; i < CFArrayGetCount (runArray); ++i)\r
             {\r
-                CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (runArray, i);\r
-                CFIndex length = CTRunGetGlyphCount (run);\r
+                auto run = (CTRunRef) CFArrayGetValueAtIndex (runArray, i);\r
+                auto length = CTRunGetGlyphCount (run);\r
 \r
                 const CoreTextTypeLayout::Advances advances (run, length);\r
 \r
@@ -681,17 +597,17 @@ public:
         {\r
             float x = 0;\r
 \r
-            CFStringRef cfText = text.toCFString();\r
-            CFAttributedStringRef attribString = CFAttributedStringCreate (kCFAllocatorDefault, cfText, attributedStringAtts);\r
+            auto cfText = text.toCFString();\r
+            auto attribString = CFAttributedStringCreate (kCFAllocatorDefault, cfText, attributedStringAtts);\r
             CFRelease (cfText);\r
 \r
-            CTLineRef line = CTLineCreateWithAttributedString (attribString);\r
-            CFArrayRef runArray = CTLineGetGlyphRuns (line);\r
+            auto line = CTLineCreateWithAttributedString (attribString);\r
+            auto runArray = CTLineGetGlyphRuns (line);\r
 \r
             for (CFIndex i = 0; i < CFArrayGetCount (runArray); ++i)\r
             {\r
-                CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (runArray, i);\r
-                CFIndex length = CTRunGetGlyphCount (run);\r
+                auto run = (CTRunRef) CFArrayGetValueAtIndex (runArray, i);\r
+                auto length = CTRunGetGlyphCount (run);\r
 \r
                 const CoreTextTypeLayout::Advances advances (run, length);\r
                 const CoreTextTypeLayout::Glyphs glyphs (run, (size_t) length);\r
@@ -713,38 +629,39 @@ public:
     {\r
         jassert (path.isEmpty());  // we might need to apply a transform to the path, so this must be empty\r
 \r
-        CGPathRef pathRef = CTFontCreatePathForGlyph (ctFontRef, (CGGlyph) glyphNumber, &renderingTransform);\r
-        if (pathRef == 0)\r
-            return false;\r
+        if (auto pathRef = CTFontCreatePathForGlyph (ctFontRef, (CGGlyph) glyphNumber, &renderingTransform))\r
+        {\r
+            CGPathApply (pathRef, &path, pathApplier);\r
+            CFRelease (pathRef);\r
 \r
-        CGPathApply (pathRef, &path, pathApplier);\r
-        CFRelease (pathRef);\r
+            if (! pathTransform.isIdentity())\r
+                path.applyTransform (pathTransform);\r
 \r
-        if (! pathTransform.isIdentity())\r
-            path.applyTransform (pathTransform);\r
+            return true;\r
+        }\r
 \r
-        return true;\r
+        return false;\r
     }\r
 \r
     //==============================================================================\r
-    CGFontRef fontRef;\r
-    CTFontRef ctFontRef;\r
+    CGFontRef fontRef = {};\r
+    CTFontRef ctFontRef = {};\r
 \r
-    float fontHeightToPointsFactor;\r
-    CGAffineTransform renderingTransform;\r
+    float fontHeightToPointsFactor = 1.0f;\r
+    CGAffineTransform renderingTransform = CGAffineTransformIdentity;\r
 \r
-    bool isMemoryFont;\r
+    const bool isMemoryFont;\r
 \r
 private:\r
     MemoryBlock dataCopy;\r
-    CFDictionaryRef attributedStringAtts;\r
-    float ascent, unitsToHeightScaleFactor;\r
+    CFDictionaryRef attributedStringAtts = {};\r
+    float ascent = 0, unitsToHeightScaleFactor = 0;\r
     AffineTransform pathTransform;\r
 \r
-    static void pathApplier (void* info, const CGPathElement* const element)\r
+    static void pathApplier (void* info, const CGPathElement* element)\r
     {\r
-        Path& path = *static_cast<Path*> (info);\r
-        const CGPoint* const p = element->points;\r
+        auto& path = *static_cast<Path*> (info);\r
+        auto* p = element->points;\r
 \r
         switch (element->type)\r
         {\r
@@ -765,23 +682,23 @@ private:
 \r
 CTFontRef getCTFontFromTypeface (const Font& f)\r
 {\r
-    if (OSXTypeface* tf = dynamic_cast<OSXTypeface*> (f.getTypeface()))\r
+    if (auto* tf = dynamic_cast<OSXTypeface*> (f.getTypeface()))\r
         return tf->ctFontRef;\r
 \r
-    return 0;\r
+    return {};\r
 }\r
 \r
 StringArray Font::findAllTypefaceNames()\r
 {\r
     StringArray names;\r
 \r
-   #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 && ! JUCE_IOS\r
+   #if JUCE_MAC\r
     // CTFontManager only exists on OS X 10.6 and later, it does not exist on iOS\r
-    CFArrayRef fontFamilyArray = CTFontManagerCopyAvailableFontFamilyNames();\r
+    auto fontFamilyArray = CTFontManagerCopyAvailableFontFamilyNames();\r
 \r
     for (CFIndex i = 0; i < CFArrayGetCount (fontFamilyArray); ++i)\r
     {\r
-        const String family (String::fromCFString ((CFStringRef) CFArrayGetValueAtIndex (fontFamilyArray, i)));\r
+        auto family = String::fromCFString ((CFStringRef) CFArrayGetValueAtIndex (fontFamilyArray, i));\r
 \r
         if (! family.startsWithChar ('.')) // ignore fonts that start with a '.'\r
             names.addIfNotAlreadyThere (family);\r
@@ -789,14 +706,14 @@ StringArray Font::findAllTypefaceNames()
 \r
     CFRelease (fontFamilyArray);\r
    #else\r
-    CTFontCollectionRef fontCollectionRef = CTFontCollectionCreateFromAvailableFonts (nullptr);\r
-    CFArrayRef fontDescriptorArray = CTFontCollectionCreateMatchingFontDescriptors (fontCollectionRef);\r
+    auto fontCollectionRef = CTFontCollectionCreateFromAvailableFonts (nullptr);\r
+    auto fontDescriptorArray = CTFontCollectionCreateMatchingFontDescriptors (fontCollectionRef);\r
     CFRelease (fontCollectionRef);\r
 \r
     for (CFIndex i = 0; i < CFArrayGetCount (fontDescriptorArray); ++i)\r
     {\r
-        CTFontDescriptorRef ctFontDescriptorRef = (CTFontDescriptorRef) CFArrayGetValueAtIndex (fontDescriptorArray, i);\r
-        CFStringRef cfsFontFamily = (CFStringRef) CTFontDescriptorCopyAttribute (ctFontDescriptorRef, kCTFontFamilyNameAttribute);\r
+        auto ctFontDescriptorRef = (CTFontDescriptorRef) CFArrayGetValueAtIndex (fontDescriptorArray, i);\r
+        auto cfsFontFamily = (CFStringRef) CTFontDescriptorCopyAttribute (ctFontDescriptorRef, kCTFontFamilyNameAttribute);\r
 \r
         names.addIfNotAlreadyThere (String::fromCFString (cfsFontFamily));\r
 \r
@@ -817,31 +734,32 @@ StringArray Font::findAllTypefaceStyles (const String& family)
 \r
     StringArray results;\r
 \r
-    CFStringRef cfsFontFamily = family.toCFString();\r
+    auto cfsFontFamily = family.toCFString();\r
     CFStringRef keys[] = { kCTFontFamilyNameAttribute };\r
     CFTypeRef values[] = { cfsFontFamily };\r
 \r
-    CFDictionaryRef fontDescAttributes = CFDictionaryCreate (nullptr, (const void**) &keys, (const void**) &values, numElementsInArray (keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);\r
+    auto fontDescAttributes = CFDictionaryCreate (nullptr, (const void**) &keys, (const void**) &values, numElementsInArray (keys),\r
+                                                  &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);\r
     CFRelease (cfsFontFamily);\r
 \r
-    CTFontDescriptorRef ctFontDescRef = CTFontDescriptorCreateWithAttributes (fontDescAttributes);\r
+    auto ctFontDescRef = CTFontDescriptorCreateWithAttributes (fontDescAttributes);\r
     CFRelease (fontDescAttributes);\r
 \r
-    CFArrayRef fontFamilyArray = CFArrayCreate (kCFAllocatorDefault, (const void**) &ctFontDescRef, 1, &kCFTypeArrayCallBacks);\r
+    auto fontFamilyArray = CFArrayCreate (kCFAllocatorDefault, (const void**) &ctFontDescRef, 1, &kCFTypeArrayCallBacks);\r
     CFRelease (ctFontDescRef);\r
 \r
-    CTFontCollectionRef fontCollectionRef = CTFontCollectionCreateWithFontDescriptors (fontFamilyArray, nullptr);\r
+    auto fontCollectionRef = CTFontCollectionCreateWithFontDescriptors (fontFamilyArray, nullptr);\r
     CFRelease (fontFamilyArray);\r
 \r
-    CFArrayRef fontDescriptorArray = CTFontCollectionCreateMatchingFontDescriptors (fontCollectionRef);\r
+    auto fontDescriptorArray = CTFontCollectionCreateMatchingFontDescriptors (fontCollectionRef);\r
     CFRelease (fontCollectionRef);\r
 \r
     if (fontDescriptorArray != nullptr)\r
     {\r
         for (CFIndex i = 0; i < CFArrayGetCount (fontDescriptorArray); ++i)\r
         {\r
-            CTFontDescriptorRef ctFontDescriptorRef = (CTFontDescriptorRef) CFArrayGetValueAtIndex (fontDescriptorArray, i);\r
-            CFStringRef cfsFontStyle = (CFStringRef) CTFontDescriptorCopyAttribute (ctFontDescriptorRef, kCTFontStyleNameAttribute);\r
+            auto ctFontDescriptorRef = (CTFontDescriptorRef) CFArrayGetValueAtIndex (fontDescriptorArray, i);\r
+            auto cfsFontStyle = (CFStringRef) CTFontDescriptorCopyAttribute (ctFontDescriptorRef, kCTFontStyleNameAttribute);\r
             results.add (String::fromCFString (cfsFontStyle));\r
             CFRelease (cfsFontStyle);\r
         }\r
@@ -852,321 +770,10 @@ StringArray Font::findAllTypefaceStyles (const String& family)
     return results;\r
 }\r
 \r
-#else\r
 \r
 //==============================================================================\r
-class OSXTypeface  : public Typeface\r
-{\r
-public:\r
-    OSXTypeface (const Font& font)\r
-        : Typeface (font.getTypefaceName(), font.getTypefaceStyle())\r
-    {\r
-        JUCE_AUTORELEASEPOOL\r
-        {\r
-            renderingTransform = CGAffineTransformIdentity;\r
-\r
-            NSDictionary* nsDict = [NSDictionary dictionaryWithObjectsAndKeys:\r
-                                       juceStringToNS (name), NSFontFamilyAttribute,\r
-                                       juceStringToNS (style), NSFontFaceAttribute, nil];\r
-\r
-            NSFontDescriptor* nsFontDesc = [NSFontDescriptor fontDescriptorWithFontAttributes: nsDict];\r
-            nsFont = [NSFont fontWithDescriptor: nsFontDesc size: referenceFontSize];\r
-\r
-            [nsFont retain];\r
-\r
-            fontRef = CGFontCreateWithFontName ((CFStringRef) [nsFont fontName]);\r
-\r
-            const float absAscent = std::abs ((float) CGFontGetAscent (fontRef));\r
-            const float totalHeight = absAscent + std::abs ((float) CGFontGetDescent (fontRef));\r
-\r
-            ascent = absAscent / totalHeight;\r
-            unitsToHeightScaleFactor = 1.0f / totalHeight;\r
-\r
-            const float nsFontAscent  = std::abs ([nsFont ascender]);\r
-            const float nsFontDescent = std::abs ([nsFont descender]);\r
-\r
-            fontHeightToPointsFactor = referenceFontSize / (nsFontAscent + nsFontDescent);\r
-\r
-            pathTransform = AffineTransform::scale (unitsToHeightScaleFactor);\r
-        }\r
-    }\r
-\r
-    ~OSXTypeface()\r
-    {\r
-       #if ! JUCE_IOS\r
-        [nsFont release];\r
-       #endif\r
-\r
-        if (fontRef != 0)\r
-            CGFontRelease (fontRef);\r
-    }\r
-\r
-    float getAscent() const override                 { return ascent; }\r
-    float getDescent() const override                { return 1.0f - ascent; }\r
-    float getHeightToPointsFactor() const override   { return fontHeightToPointsFactor; }\r
-\r
-    float getStringWidth (const String& text) override\r
-    {\r
-        if (fontRef == 0 || text.isEmpty())\r
-            return 0;\r
-\r
-        const int length = text.length();\r
-        HeapBlock<CGGlyph> glyphs;\r
-        createGlyphsForString (text.getCharPointer(), length, glyphs);\r
-\r
-        float x = 0;\r
-\r
-        HeapBlock<int> advances (length);\r
-\r
-        if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances))\r
-            for (int i = 0; i < length; ++i)\r
-                x += advances[i];\r
-\r
-        return x * unitsToHeightScaleFactor;\r
-    }\r
-\r
-    void getGlyphPositions (const String& text, Array<int>& resultGlyphs, Array<float>& xOffsets) override\r
-    {\r
-        xOffsets.add (0);\r
-\r
-        if (fontRef == 0 || text.isEmpty())\r
-            return;\r
-\r
-        const int length = text.length();\r
-        HeapBlock<CGGlyph> glyphs;\r
-        createGlyphsForString (text.getCharPointer(), length, glyphs);\r
-\r
-        HeapBlock<int> advances (length);\r
-\r
-        if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances))\r
-        {\r
-            int x = 0;\r
-            for (int i = 0; i < length; ++i)\r
-            {\r
-                x += advances [i];\r
-                xOffsets.add (x * unitsToHeightScaleFactor);\r
-                resultGlyphs.add (glyphs[i]);\r
-            }\r
-        }\r
-    }\r
-\r
-    bool getOutlineForGlyph (int glyphNumber, Path& path) override\r
-    {\r
-       #if JUCE_IOS\r
-        return false;\r
-       #else\r
-        if (nsFont == nil)\r
-            return false;\r
-\r
-        // we might need to apply a transform to the path, so it mustn't have anything else in it\r
-        jassert (path.isEmpty());\r
-\r
-        JUCE_AUTORELEASEPOOL\r
-        {\r
-            NSBezierPath* bez = [NSBezierPath bezierPath];\r
-            [bez moveToPoint: NSMakePoint (0, 0)];\r
-            [bez appendBezierPathWithGlyph: (NSGlyph) glyphNumber\r
-                                    inFont: nsFont];\r
-\r
-            for (int i = 0; i < [bez elementCount]; ++i)\r
-            {\r
-                NSPoint p[3];\r
-                switch ([bez elementAtIndex: i associatedPoints: p])\r
-                {\r
-                    case NSMoveToBezierPathElement:     path.startNewSubPath ((float) p[0].x, (float) -p[0].y); break;\r
-                    case NSLineToBezierPathElement:     path.lineTo  ((float) p[0].x, (float) -p[0].y); break;\r
-                    case NSCurveToBezierPathElement:    path.cubicTo ((float) p[0].x, (float) -p[0].y,\r
-                                                                      (float) p[1].x, (float) -p[1].y,\r
-                                                                      (float) p[2].x, (float) -p[2].y); break;\r
-                    case NSClosePathBezierPathElement:  path.closeSubPath(); break;\r
-                    default:                            jassertfalse; break;\r
-                }\r
-            }\r
-\r
-            path.applyTransform (pathTransform);\r
-        }\r
-        return true;\r
-       #endif\r
-    }\r
-\r
-    //==============================================================================\r
-    CGFontRef fontRef;\r
-    float fontHeightToPointsFactor;\r
-    CGAffineTransform renderingTransform;\r
-\r
-private:\r
-    float ascent, unitsToHeightScaleFactor;\r
-\r
-   #if ! JUCE_IOS\r
-    NSFont* nsFont;\r
-    AffineTransform pathTransform;\r
-   #endif\r
-\r
-    void createGlyphsForString (String::CharPointerType text, const int length, HeapBlock<CGGlyph>& glyphs)\r
-    {\r
-        if (charToGlyphMapper == nullptr)\r
-            charToGlyphMapper = new CharToGlyphMapper (fontRef);\r
-\r
-        glyphs.malloc (length);\r
-\r
-        for (int i = 0; i < length; ++i)\r
-            glyphs[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text.getAndAdvance());\r
-    }\r
-\r
-    // Reads a CGFontRef's character map table to convert unicode into glyph numbers\r
-    class CharToGlyphMapper\r
-    {\r
-    public:\r
-        CharToGlyphMapper (CGFontRef cgFontRef)\r
-            : segCount (0), endCode (0), startCode (0), idDelta (0),\r
-              idRangeOffset (0), glyphIndexes (0)\r
-        {\r
-            CFDataRef cmapTable = CGFontCopyTableForTag (cgFontRef, 'cmap');\r
-\r
-            if (cmapTable != 0)\r
-            {\r
-                const int numSubtables = getValue16 (cmapTable, 2);\r
-\r
-                for (int i = 0; i < numSubtables; ++i)\r
-                {\r
-                    if (getValue16 (cmapTable, i * 8 + 4) == 0) // check for platform ID of 0\r
-                    {\r
-                        const int offset = getValue32 (cmapTable, i * 8 + 8);\r
-\r
-                        if (getValue16 (cmapTable, offset) == 4) // check that it's format 4..\r
-                        {\r
-                            const int length = getValue16 (cmapTable, offset + 2);\r
-                            const int segCountX2 =  getValue16 (cmapTable, offset + 6);\r
-                            segCount = segCountX2 / 2;\r
-                            const int endCodeOffset = offset + 14;\r
-                            const int startCodeOffset = endCodeOffset + 2 + segCountX2;\r
-                            const int idDeltaOffset = startCodeOffset + segCountX2;\r
-                            const int idRangeOffsetOffset = idDeltaOffset + segCountX2;\r
-                            const int glyphIndexesOffset = idRangeOffsetOffset + segCountX2;\r
-\r
-                            endCode       = CFDataCreate (kCFAllocatorDefault, CFDataGetBytePtr (cmapTable) + endCodeOffset, segCountX2);\r
-                            startCode     = CFDataCreate (kCFAllocatorDefault, CFDataGetBytePtr (cmapTable) + startCodeOffset, segCountX2);\r
-                            idDelta       = CFDataCreate (kCFAllocatorDefault, CFDataGetBytePtr (cmapTable) + idDeltaOffset, segCountX2);\r
-                            idRangeOffset = CFDataCreate (kCFAllocatorDefault, CFDataGetBytePtr (cmapTable) + idRangeOffsetOffset, segCountX2);\r
-                            glyphIndexes  = CFDataCreate (kCFAllocatorDefault, CFDataGetBytePtr (cmapTable) + glyphIndexesOffset, offset + length - glyphIndexesOffset);\r
-                        }\r
-\r
-                        break;\r
-                    }\r
-                }\r
-\r
-                CFRelease (cmapTable);\r
-            }\r
-        }\r
-\r
-        ~CharToGlyphMapper()\r
-        {\r
-            if (endCode != 0)\r
-            {\r
-                CFRelease (endCode);\r
-                CFRelease (startCode);\r
-                CFRelease (idDelta);\r
-                CFRelease (idRangeOffset);\r
-                CFRelease (glyphIndexes);\r
-            }\r
-        }\r
-\r
-        int getGlyphForCharacter (const juce_wchar c) const\r
-        {\r
-            for (int i = 0; i < segCount; ++i)\r
-            {\r
-                if (getValue16 (endCode, i * 2) >= c)\r
-                {\r
-                    const int start = getValue16 (startCode, i * 2);\r
-                    if (start > c)\r
-                        break;\r
-\r
-                    const int delta = getValue16 (idDelta, i * 2);\r
-                    const int rangeOffset = getValue16 (idRangeOffset, i * 2);\r
-\r
-                    if (rangeOffset == 0)\r
-                        return delta + c;\r
-\r
-                    return getValue16 (glyphIndexes, 2 * ((rangeOffset / 2) + (c - start) - (segCount - i)));\r
-                }\r
-            }\r
-\r
-            // If we failed to find it "properly", this dodgy fall-back seems to do the trick for most fonts!\r
-            return jmax (-1, (int) c - 29);\r
-        }\r
-\r
-    private:\r
-        int segCount;\r
-        CFDataRef endCode, startCode, idDelta, idRangeOffset, glyphIndexes;\r
-\r
-        static uint16 getValue16 (CFDataRef data, const int index)\r
-        {\r
-            return CFSwapInt16BigToHost (*(UInt16*) (CFDataGetBytePtr (data) + index));\r
-        }\r
-\r
-        static uint32 getValue32 (CFDataRef data, const int index)\r
-        {\r
-            return CFSwapInt32BigToHost (*(UInt32*) (CFDataGetBytePtr (data) + index));\r
-        }\r
-    };\r
-\r
-    ScopedPointer<CharToGlyphMapper> charToGlyphMapper;\r
-\r
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSXTypeface)\r
-};\r
-\r
-StringArray Font::findAllTypefaceNames()\r
-{\r
-    StringArray names;\r
-\r
-    JUCE_AUTORELEASEPOOL\r
-    {\r
-       #if JUCE_IOS\r
-        for (NSString* name in [UIFont familyNames])\r
-       #else\r
-        for (NSString* name in [[NSFontManager sharedFontManager] availableFontFamilies])\r
-       #endif\r
-            names.add (nsStringToJuce (name));\r
-\r
-        names.sort (true);\r
-    }\r
-\r
-    return names;\r
-}\r
-\r
-StringArray Font::findAllTypefaceStyles (const String& family)\r
-{\r
-    if (FontStyleHelpers::isPlaceholderFamilyName (family))\r
-        return findAllTypefaceStyles (FontStyleHelpers::getConcreteFamilyNameFromPlaceholder (family));\r
-\r
-    StringArray results;\r
-\r
-    JUCE_AUTORELEASEPOOL\r
-    {\r
-        for (NSArray* style in [[NSFontManager sharedFontManager] availableMembersOfFontFamily: juceStringToNS (family)])\r
-            results.add (nsStringToJuce ((NSString*) [style objectAtIndex: 1]));\r
-    }\r
-\r
-    return results;\r
-}\r
-\r
-#endif\r
-\r
-//==============================================================================\r
-Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font)\r
-{\r
-    return new OSXTypeface (font);\r
-}\r
-\r
-Typeface::Ptr Typeface::createSystemTypefaceFor (const void* data, size_t dataSize)\r
-{\r
-   #if JUCE_CORETEXT_AVAILABLE\r
-    return new OSXTypeface (data, dataSize);\r
-   #else\r
-    jassertfalse; // You need CoreText enabled to use this feature!\r
-    return nullptr;\r
-   #endif\r
-}\r
+Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font)                  { return new OSXTypeface (font); }\r
+Typeface::Ptr Typeface::createSystemTypefaceFor (const void* data, size_t size)     { return new OSXTypeface (data, size); }\r
 \r
 void Typeface::scanFolderForFonts (const File&)\r
 {\r
@@ -1175,29 +782,23 @@ void Typeface::scanFolderForFonts (const File&)
 \r
 struct DefaultFontNames\r
 {\r
-    DefaultFontNames()\r
-       #if JUCE_IOS\r
-        : defaultSans  ("Helvetica"),\r
-          defaultSerif ("Times New Roman"),\r
-          defaultFixed ("Courier New"),\r
-       #else\r
-        : defaultSans  ("Lucida Grande"),\r
-          defaultSerif ("Times New Roman"),\r
-          defaultFixed ("Menlo"),\r
-       #endif\r
-          defaultFallback ("Arial Unicode MS")\r
-    {\r
-    }\r
-\r
-    String defaultSans, defaultSerif, defaultFixed, defaultFallback;\r
+   #if JUCE_IOS\r
+    String defaultSans  { "Helvetica" },\r
+           defaultSerif { "Times New Roman" },\r
+           defaultFixed { "Courier New" };\r
+   #else\r
+    String defaultSans  { "Lucida Grande" },\r
+           defaultSerif { "Times New Roman" },\r
+           defaultFixed { "Menlo" };\r
+   #endif\r
 };\r
 \r
 Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)\r
 {\r
     static DefaultFontNames defaultNames;\r
 \r
-    Font newFont (font);\r
-    const String& faceName = font.getTypefaceName();\r
+    auto newFont = font;\r
+    auto& faceName = font.getTypefaceName();\r
 \r
     if (faceName == getDefaultSansSerifFontName())       newFont.setTypefaceName (defaultNames.defaultSans);\r
     else if (faceName == getDefaultSerifFontName())      newFont.setTypefaceName (defaultNames.defaultSerif);\r
@@ -1209,16 +810,28 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
     return Typeface::createSystemTypefaceFor (newFont);\r
 }\r
 \r
-#if JUCE_CORETEXT_AVAILABLE\r
+// Due to an old and unfathomable bug in CoreText which prevents the layout working with\r
+// typefaces that were loaded from memory, this function checks whether we need to use a\r
+// fallback layout algorithm.\r
 static bool canAllTypefacesBeUsedInLayout (const AttributedString& text)\r
 {\r
-    const int numCharacterAttributes = text.getNumAttributes();\r
+   #if JUCE_MAC && defined (MAC_OS_X_VERSION_10_11) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11\r
+    ignoreUnused (text);\r
+    return true;\r
+   #else\r
+\r
+   #if JUCE_MAC\r
+    if (SystemStats::getOperatingSystemType() >= SystemStats::OperatingSystemType::MacOSX_10_11)\r
+        return true;\r
+   #endif\r
+\r
+    auto numCharacterAttributes = text.getNumAttributes();\r
 \r
     for (int i = 0; i < numCharacterAttributes; ++i)\r
     {\r
-        Typeface* t = text.getAttribute(i).font.getTypeface();\r
+        auto* t = text.getAttribute(i).font.getTypeface();\r
 \r
-        if (OSXTypeface* tf = dynamic_cast<OSXTypeface*> (t))\r
+        if (auto tf = dynamic_cast<OSXTypeface*> (t))\r
         {\r
             if (tf->isMemoryFont)\r
                 return false;\r
@@ -1230,20 +843,16 @@ static bool canAllTypefacesBeUsedInLayout (const AttributedString& text)
     }\r
 \r
     return true;\r
+   #endif\r
 }\r
-#endif\r
 \r
 bool TextLayout::createNativeLayout (const AttributedString& text)\r
 {\r
-   #if JUCE_CORETEXT_AVAILABLE\r
-    // Seems to be an unfathomable bug in CoreText which prevents the layout working with\r
-    // typefaces that were loaded from memory, so have to fallback if we hit any of those..\r
     if (canAllTypefacesBeUsedInLayout (text))\r
     {\r
         CoreTextTypeLayout::createLayout (*this, text);\r
         return true;\r
     }\r
-   #endif\r
 \r
     ignoreUnused (text);\r
     return false;\r
index ba0cf99e4a6c8bb6e434187b2d75fd36084ae35a..46ccb997baac6b73453db18319edf1062bca176a 100644 (file)
@@ -65,8 +65,9 @@ public:
         }\r
     }\r
 \r
+    template <typename ...Params>\r
     static void sendMouseEvent (Component& comp, Component::BailOutChecker& checker,\r
-                                void (MouseListener::*eventMethod) (const MouseEvent&), const MouseEvent& e)\r
+                                void (MouseListener::*eventMethod) (Params...), Params... params)\r
     {\r
         if (checker.shouldBailOut())\r
             return;\r
@@ -75,7 +76,7 @@ public:
         {\r
             for (int i = list->listeners.size(); --i >= 0;)\r
             {\r
-                (list->listeners.getUnchecked(i)->*eventMethod) (e);\r
+                (list->listeners.getUnchecked(i)->*eventMethod) (params...);\r
 \r
                 if (checker.shouldBailOut())\r
                     return;\r
@@ -94,45 +95,7 @@ public:
 \r
                     for (int i = list->numDeepMouseListeners; --i >= 0;)\r
                     {\r
-                        (list->listeners.getUnchecked(i)->*eventMethod) (e);\r
-\r
-                        if (checker2.shouldBailOut())\r
-                            return;\r
-\r
-                        i = jmin (i, list->numDeepMouseListeners);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    static void sendWheelEvent (Component& comp, Component::BailOutChecker& checker,\r
-                                const MouseEvent& e, const MouseWheelDetails& wheel)\r
-    {\r
-        if (auto* list = comp.mouseListeners.get())\r
-        {\r
-            for (int i = list->listeners.size(); --i >= 0;)\r
-            {\r
-                list->listeners.getUnchecked(i)->mouseWheelMove (e, wheel);\r
-\r
-                if (checker.shouldBailOut())\r
-                    return;\r
-\r
-                i = jmin (i, list->listeners.size());\r
-            }\r
-        }\r
-\r
-        for (Component* p = comp.parentComponent; p != nullptr; p = p->parentComponent)\r
-        {\r
-            if (auto* list = p->mouseListeners.get())\r
-            {\r
-                if (list->numDeepMouseListeners > 0)\r
-                {\r
-                    BailOutChecker2 checker2 (checker, p);\r
-\r
-                    for (int i = list->numDeepMouseListeners; --i >= 0;)\r
-                    {\r
-                        list->listeners.getUnchecked(i)->mouseWheelMove (e, wheel);\r
+                        (list->listeners.getUnchecked(i)->*eventMethod) (params...);\r
 \r
                         if (checker2.shouldBailOut())\r
                             return;\r
@@ -2303,7 +2266,7 @@ void Component::internalMouseEnter (MouseInputSource source, Point<float> relati
 \r
     Desktop::getInstance().getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseEnter (me); });\r
 \r
-    MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseEnter, me);\r
+    MouseListenerList::template sendMouseEvent<const MouseEvent&> (*this, checker, &MouseListener::mouseEnter, me);\r
 }\r
 \r
 void Component::internalMouseExit (MouseInputSource source, Point<float> relativePos, Time time)\r
@@ -2332,7 +2295,7 @@ void Component::internalMouseExit (MouseInputSource source, Point<float> relativ
 \r
     Desktop::getInstance().getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseExit (me); });\r
 \r
-    MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseExit, me);\r
+    MouseListenerList::template sendMouseEvent<const MouseEvent&> (*this, checker, &MouseListener::mouseExit, me);\r
 }\r
 \r
 void Component::internalMouseDown (MouseInputSource source, Point<float> relativePos, Time time,\r
@@ -2397,7 +2360,7 @@ void Component::internalMouseDown (MouseInputSource source, Point<float> relativ
 \r
     desktop.getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseDown (me); });\r
 \r
-    MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseDown, me);\r
+    MouseListenerList::template sendMouseEvent<const MouseEvent&> (*this, checker, &MouseListener::mouseDown, me);\r
 }\r
 \r
 void Component::internalMouseUp (MouseInputSource source, Point<float> relativePos, Time time,\r
@@ -2416,7 +2379,7 @@ void Component::internalMouseUp (MouseInputSource source, Point<float> relativeP
                          getLocalPoint (nullptr, source.getLastMouseDownPosition()),\r
                          source.getLastMouseDownTime(),\r
                          source.getNumberOfMultipleClicks(),\r
-                         source.hasMouseMovedSignificantlySincePressed());\r
+                         source.isLongPressOrDrag());\r
     mouseUp (me);\r
 \r
     if (checker.shouldBailOut())\r
@@ -2425,7 +2388,7 @@ void Component::internalMouseUp (MouseInputSource source, Point<float> relativeP
     auto& desktop = Desktop::getInstance();\r
     desktop.getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseUp (me); });\r
 \r
-    MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseUp, me);\r
+    MouseListenerList::template sendMouseEvent<const MouseEvent&> (*this, checker, &MouseListener::mouseUp, me);\r
 \r
     if (checker.shouldBailOut())\r
         return;\r
@@ -2439,7 +2402,7 @@ void Component::internalMouseUp (MouseInputSource source, Point<float> relativeP
             return;\r
 \r
         desktop.mouseListeners.callChecked (checker, [&] (MouseListener& l) { l.mouseDoubleClick (me); });\r
-        MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseDoubleClick, me);\r
+        MouseListenerList::template sendMouseEvent<const MouseEvent&> (*this, checker, &MouseListener::mouseDoubleClick, me);\r
     }\r
 }\r
 \r
@@ -2455,7 +2418,7 @@ void Component::internalMouseDrag (MouseInputSource source, Point<float> relativ
                              getLocalPoint (nullptr, source.getLastMouseDownPosition()),\r
                              source.getLastMouseDownTime(),\r
                              source.getNumberOfMultipleClicks(),\r
-                             source.hasMouseMovedSignificantlySincePressed());\r
+                             source.isLongPressOrDrag());\r
         mouseDrag (me);\r
 \r
         if (checker.shouldBailOut())\r
@@ -2463,7 +2426,7 @@ void Component::internalMouseDrag (MouseInputSource source, Point<float> relativ
 \r
         Desktop::getInstance().getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseDrag (me); });\r
 \r
-        MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseDrag, me);\r
+        MouseListenerList::template sendMouseEvent<const MouseEvent&> (*this, checker, &MouseListener::mouseDrag, me);\r
     }\r
 }\r
 \r
@@ -2491,7 +2454,7 @@ void Component::internalMouseMove (MouseInputSource source, Point<float> relativ
 \r
         desktop.getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseMove (me); });\r
 \r
-        MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseMove, me);\r
+        MouseListenerList::template sendMouseEvent<const MouseEvent&> (*this, checker, &MouseListener::mouseMove, me);\r
     }\r
 }\r
 \r
@@ -2521,21 +2484,37 @@ void Component::internalMouseWheel (MouseInputSource source, Point<float> relati
         desktop.mouseListeners.callChecked (checker, [&] (MouseListener& l) { l.mouseWheelMove (me, wheel); });\r
 \r
         if (! checker.shouldBailOut())\r
-            MouseListenerList::sendWheelEvent (*this, checker, me, wheel);\r
+            MouseListenerList::template sendMouseEvent<const MouseEvent&, const MouseWheelDetails&> (*this, checker, &MouseListener::mouseWheelMove, me, wheel);\r
     }\r
 }\r
 \r
 void Component::internalMagnifyGesture (MouseInputSource source, Point<float> relativePos,\r
                                         Time time, float amount)\r
 {\r
-    if (! isCurrentlyBlockedByAnotherModalComponent())\r
-    {\r
-        const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure,\r
+    auto& desktop = Desktop::getInstance();\r
+    BailOutChecker checker (this);\r
+\r
+    const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure,\r
                              MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation,\r
                              MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY,\r
                              this, this, time, relativePos, time, 0, false);\r
 \r
+    if (isCurrentlyBlockedByAnotherModalComponent())\r
+    {\r
+        // allow blocked mouse-events to go to global listeners..\r
+        desktop.mouseListeners.callChecked (checker, [&] (MouseListener& l) { l.mouseMagnify (me, amount); });\r
+    }\r
+    else\r
+    {\r
         mouseMagnify (me, amount);\r
+\r
+        if (checker.shouldBailOut())\r
+            return;\r
+\r
+        desktop.mouseListeners.callChecked (checker, [&] (MouseListener& l) { l.mouseMagnify (me, amount); });\r
+\r
+        if (! checker.shouldBailOut())\r
+            MouseListenerList::template sendMouseEvent<const MouseEvent&, float> (*this, checker, &MouseListener::mouseMagnify, me, amount);\r
     }\r
 }\r
 \r
index cc4149d18075aa13ee4ff430ecef690ab8b9f22a..9b0df8b45c2bb0f719314c4a746b4e9b36e0222c 100644 (file)
@@ -1596,7 +1596,7 @@ public:
                             should be changed. A value of 1.0 would indicate no change,\r
                             values greater than 1.0 mean it should be enlarged.\r
     */\r
-    virtual void mouseMagnify (const MouseEvent& event, float scaleFactor);\r
+    virtual void mouseMagnify (const MouseEvent& event, float scaleFactor) override;\r
 \r
     //==============================================================================\r
     /** Ensures that a non-stop stream of mouse-drag events will be sent during the\r
index 126e47a4bd9d84524cefe6874c3c55a8a6e69c1b..c889e7363e7d2a031f55205b5ee6560fc2b7c24a 100644 (file)
@@ -262,12 +262,14 @@ void ContentSharer::sharingFinished (bool succeeded, const String& errorDescript
     std::function<void (bool, String)> cb;\r
     std::swap (cb, callback);\r
 \r
+    String error (errorDescription);\r
+\r
   #if JUCE_IOS || JUCE_ANDROID\r
     pimpl.reset();\r
   #endif\r
 \r
     if (cb)\r
-        cb (succeeded, errorDescription);\r
+        cb (succeeded, error);\r
 }\r
 \r
 void ContentSharer::deleteTemporaryFiles()\r
index 3645f52222dbd79aee02b05cd5ba0edaeea7ba4e..b8148e76f60233dda24b4215733eec17d98494be 100644 (file)
@@ -235,6 +235,7 @@ namespace juce
 #include "properties/juce_PropertyPanel.cpp"\r
 #include "properties/juce_SliderPropertyComponent.cpp"\r
 #include "properties/juce_TextPropertyComponent.cpp"\r
+#include "properties/juce_MultiChoicePropertyComponent.cpp"\r
 #include "widgets/juce_ComboBox.cpp"\r
 #include "widgets/juce_ImageComponent.cpp"\r
 #include "widgets/juce_Label.cpp"\r
index afaa0caccf35684e4d21c20566d8a500aa9a8d86..7103564f5c8082027fb4d520af7440b6c7324f84 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_gui_basics\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE GUI core classes\r
   description:      Basic user-interface components and related classes.\r
   website:          http://www.juce.com/juce\r
@@ -280,6 +280,7 @@ namespace juce
 #include "properties/juce_PropertyPanel.h"\r
 #include "properties/juce_SliderPropertyComponent.h"\r
 #include "properties/juce_TextPropertyComponent.h"\r
+#include "properties/juce_MultiChoicePropertyComponent.h"\r
 #include "application/juce_Application.h"\r
 #include "misc/juce_BubbleComponent.h"\r
 #include "lookandfeel/juce_LookAndFeel.h"\r
index 6bd3123bdd8f8e8e6af098cb190342719fa1fc41..721441cf264c8fd2241b57a29a431589a07027ed 100644 (file)
@@ -1017,7 +1017,7 @@ void Grid::performLayout (juce::Rectangle<int> targetArea)
                                 + targetArea.toFloat().getPosition();\r
 \r
         if (auto* c = item->associatedComponent)\r
-            c->setBounds (item->currentBounds.toNearestInt());\r
+            c->setBounds (item->currentBounds.toNearestIntEdges());\r
     }\r
 }\r
 \r
index a74ee35f4716adafed79a339d97a6f51427b9d90..7e04b3152f93c6023d2928192d6cb11c1993989c 100644 (file)
@@ -360,6 +360,12 @@ void Viewport::updateVisibleArea()
         if (vBarVisible)  contentArea.setWidth  (getWidth()  - scrollbarWidth);\r
         if (hBarVisible)  contentArea.setHeight (getHeight() - scrollbarWidth);\r
 \r
+        if (! vScrollbarRight  && vBarVisible)\r
+            contentArea.setX (scrollbarWidth);\r
+\r
+        if (! hScrollbarBottom && hBarVisible)\r
+            contentArea.setY (scrollbarWidth);\r
+\r
         if (contentComp == nullptr)\r
         {\r
             contentHolder.setBounds (contentArea);\r
@@ -383,7 +389,7 @@ void Viewport::updateVisibleArea()
     auto& hbar = getHorizontalScrollBar();\r
     auto& vbar = getVerticalScrollBar();\r
 \r
-    hbar.setBounds (0, contentArea.getHeight(), contentArea.getWidth(), scrollbarWidth);\r
+    hbar.setBounds (contentArea.getX(), hScrollbarBottom ? contentArea.getHeight() : 0, contentArea.getWidth(), scrollbarWidth);\r
     hbar.setRangeLimits (0.0, contentBounds.getWidth());\r
     hbar.setCurrentRange (visibleOrigin.x, contentArea.getWidth());\r
     hbar.setSingleStepSize (singleStepX);\r
@@ -392,7 +398,7 @@ void Viewport::updateVisibleArea()
     if (canShowHBar && ! hBarVisible)\r
         visibleOrigin.setX (0);\r
 \r
-    vbar.setBounds (contentArea.getWidth(), 0, scrollbarWidth, contentArea.getHeight());\r
+    vbar.setBounds (vScrollbarRight ? contentArea.getWidth() : 0, contentArea.getY(), scrollbarWidth, contentArea.getHeight());\r
     vbar.setRangeLimits (0.0, contentBounds.getHeight());\r
     vbar.setCurrentRange (visibleOrigin.y, contentArea.getHeight());\r
     vbar.setSingleStepSize (singleStepY);\r
@@ -599,4 +605,13 @@ ScrollBar* Viewport::createScrollBarComponent (bool isVertical)
     return new ScrollBar (isVertical);\r
 }\r
 \r
+void Viewport::setScrollBarPosition (bool verticalScrollbarOnRight,\r
+                                     bool horizontalScrollbarAtBottom)\r
+{\r
+    vScrollbarRight  = verticalScrollbarOnRight;\r
+    hScrollbarBottom = horizontalScrollbarAtBottom;\r
+\r
+    resized();\r
+}\r
+\r
 } // namespace juce\r
index 529e3beaba0d177bf0b719f89ea3869bd8435f26..f28a85a3d82cce77606880e6e3ac5ba7346f72e0 100644 (file)
@@ -204,6 +204,25 @@ public:
                              bool allowVerticalScrollingWithoutScrollbar = false,\r
                              bool allowHorizontalScrollingWithoutScrollbar = false);\r
 \r
+    /** Changes where the scroll bars are positioned\r
+\r
+        If verticalScrollbarOnRight is set to true, then the vertical scrollbar will\r
+        appear on the right side of the view port's content (this is the default),\r
+        otherwise it will be on the left side of the content.\r
+\r
+        If horizontalScrollbarAtBottom is set to true, then the horizontal scrollbar\r
+        will appear at the bottom of the view port's content (this is the default),\r
+        otherwise it will be at the top.\r
+    */\r
+    void setScrollBarPosition (bool verticalScrollbarOnRight,\r
+                               bool horizontalScrollbarAtBottom);\r
+\r
+    /** True if the vertical scrollbar will appear on the right side of the content */\r
+    bool isVerticalScrollbarOnTheRight() const noexcept         { return vScrollbarRight; }\r
+\r
+    /** True if the horizontal scrollbar will appear at the bottom of the content */\r
+    bool isHorizontalScrollbarAtBottom() const noexcept         { return hScrollbarBottom; }\r
+\r
     /** True if the vertical scrollbar is enabled.\r
         @see setScrollBarsShown\r
     */\r
@@ -300,6 +319,7 @@ private:
     bool showHScrollbar = true, showVScrollbar = true, deleteContent = true;\r
     bool customScrollBarThickness = false;\r
     bool allowScrollingWithoutScrollbarV = false, allowScrollingWithoutScrollbarH = false;\r
+    bool vScrollbarRight = true, hScrollbarBottom = true;\r
 \r
     struct DragToScrollListener;\r
     friend struct DragToScrollListener;\r
index 6c96c875a0b39d2cbf606a923a50014eea42ead1..efcf09c880ce3af476ed0fe13259026bb677920d 100644 (file)
@@ -789,7 +789,7 @@ public:
                                                     windowPos.getHeight() - (PopupMenuSettings::scrollZone + m->getHeight())),\r
                                               currentY);\r
 \r
-                        auto parentArea = getParentArea (windowPos.getPosition());\r
+                        auto parentArea = getParentArea (windowPos.getPosition()) / scaleFactor;\r
                         auto deltaY = wantedY - currentY;\r
 \r
                         windowPos.setSize (jmin (windowPos.getWidth(), parentArea.getWidth()),\r
index 59a9b7ae01605a3e3fc05e1a469409b6d640b36e..8fe3220f9ef347509a9f6038c1ede8feab83a524 100644 (file)
@@ -236,8 +236,8 @@ public:
 \r
         This is only meaningful if called in either a mouseUp() or mouseDrag() method.\r
 \r
-        It will return true if the user has dragged the mouse more than a few pixels\r
-        from the place where the mouse-down occurred.\r
+        It will return true if the user has dragged the mouse more than a few pixels from the place\r
+        where the mouse-down occurred or the mouse has been held down for a significant amount of time.\r
 \r
         Once they have dragged it far enough for this method to return true, it will continue\r
         to return true until the mouse-up, even if they move the mouse back to the same\r
index 07a9225b2c0bf27f7e7f682daaf14cbf53c822f6..4a3e0b52644faa34c27d3bea3831003fffb5bd27 100644 (file)
@@ -391,7 +391,7 @@ public:
     {\r
         int numClicks = 1;\r
 \r
-        if (! hasMouseMovedSignificantlySincePressed())\r
+        if (! isLongPressOrDrag())\r
         {\r
             for (int i = 1; i < numElementsInArray (mouseDowns); ++i)\r
             {\r
@@ -405,10 +405,20 @@ public:
         return numClicks;\r
     }\r
 \r
+    bool isLongPressOrDrag() const noexcept\r
+    {\r
+        return movedSignificantly || lastTime > mouseDowns[0].time + RelativeTime::milliseconds (300);\r
+    }\r
+\r
+    bool hasMovedSignificantlySincePressed() const noexcept\r
+    {\r
+        return movedSignificantly;\r
+    }\r
+\r
+    // Deprecated method\r
     bool hasMouseMovedSignificantlySincePressed() const noexcept\r
     {\r
-        return mouseMovedSignificantlySincePressed\r
-                || lastTime > mouseDowns[0].time + RelativeTime::milliseconds (300);\r
+        return isLongPressOrDrag();\r
     }\r
 \r
     //==============================================================================\r
@@ -539,7 +549,7 @@ private:
 \r
     RecentMouseDown mouseDowns[4];\r
     Time lastTime;\r
-    bool mouseMovedSignificantlySincePressed = false;\r
+    bool movedSignificantly = false;\r
 \r
     void registerMouseDown (Point<float> screenPos, Time time, Component& component,\r
                             const ModifierKeys modifiers, bool isTouchSource) noexcept\r
@@ -557,14 +567,13 @@ private:
         else\r
             mouseDowns[0].peerID = 0;\r
 \r
-        mouseMovedSignificantlySincePressed = false;\r
+        movedSignificantly = false;\r
         lastNonInertialWheelTarget = nullptr;\r
     }\r
 \r
     void registerMouseDrag (Point<float> screenPos) noexcept\r
     {\r
-        mouseMovedSignificantlySincePressed = mouseMovedSignificantlySincePressed\r
-               || mouseDowns[0].position.getDistanceFrom (screenPos) >= 4;\r
+        movedSignificantly = movedSignificantly || mouseDowns[0].position.getDistanceFrom (screenPos) >= 4;\r
     }\r
 \r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MouseInputSourceInternal)\r
@@ -605,7 +614,8 @@ void MouseInputSource::triggerFakeMove() const
 int MouseInputSource::getNumberOfMultipleClicks() const noexcept                { return pimpl->getNumberOfMultipleClicks(); }\r
 Time MouseInputSource::getLastMouseDownTime() const noexcept                    { return pimpl->getLastMouseDownTime(); }\r
 Point<float> MouseInputSource::getLastMouseDownPosition() const noexcept        { return pimpl->getLastMouseDownPosition(); }\r
-bool MouseInputSource::hasMouseMovedSignificantlySincePressed() const noexcept  { return pimpl->hasMouseMovedSignificantlySincePressed(); }\r
+bool MouseInputSource::isLongPressOrDrag() const noexcept                       { return pimpl->isLongPressOrDrag(); }\r
+bool MouseInputSource::hasMovedSignificantlySincePressed() const noexcept       { return pimpl->hasMovedSignificantlySincePressed(); }\r
 bool MouseInputSource::canDoUnboundedMovement() const noexcept                  { return ! isTouch(); }\r
 void MouseInputSource::enableUnboundedMouseMovement (bool isEnabled, bool keepCursorVisibleUntilOffscreen) const\r
                                                                          { pimpl->enableUnboundedMouseMovement (isEnabled, keepCursorVisibleUntilOffscreen); }\r
@@ -640,6 +650,9 @@ const float MouseInputSource::invalidRotation = 0.0f;
 const float MouseInputSource::invalidTiltX = 0.0f;\r
 const float MouseInputSource::invalidTiltY = 0.0f;\r
 \r
+// Deprecated method\r
+bool MouseInputSource::hasMouseMovedSignificantlySincePressed() const noexcept  { return pimpl->hasMouseMovedSignificantlySincePressed(); }\r
+\r
 //==============================================================================\r
 struct MouseInputSource::SourceList  : public Timer\r
 {\r
index 523b8fd2f692cf2bcf13b753c68a52b90eabba08..11e13b2c3b9c54a9c149aa0feb25cb34e3d21940 100644 (file)
@@ -172,10 +172,12 @@ public:
     /** Returns the screen position at which the last mouse-down occurred. */\r
     Point<float> getLastMouseDownPosition() const noexcept;\r
 \r
-    /** Returns true if this mouse is currently down, and if it has been dragged more\r
-        than a couple of pixels from the place it was pressed.\r
-    */\r
-    bool hasMouseMovedSignificantlySincePressed() const noexcept;\r
+    /** Returns true if this input source represents a long-press or drag interaction i.e. it has been held down for a significant\r
+        amount of time or it has been dragged more than a couple of pixels from the place it was pressed. */\r
+    bool isLongPressOrDrag() const noexcept;\r
+\r
+    /** Returns true if this input source has been dragged more than a couple of pixels from the place it was pressed. */\r
+    bool hasMovedSignificantlySincePressed() const noexcept;\r
 \r
     /** Returns true if this input source uses a visible mouse cursor. */\r
     bool hasMouseCursor() const noexcept;\r
@@ -235,6 +237,13 @@ public:
     static const float invalidTiltX;\r
     static const float invalidTiltY;\r
 \r
+   #if ! DOXYGEN\r
+    // This method has been deprecated and replaced with the isLongPressOrDrag() and hasMovedSignificantlySincePressed()\r
+    // methods. If you want the same behaviour you should use isLongPressOrDrag() which accounts for the amount of time\r
+    // that the input source has been held down for, but if you only want to know whether it has been moved use\r
+    // hasMovedSignificantlySincePressed() instead.\r
+    JUCE_DEPRECATED (bool hasMouseMovedSignificantlySincePressed() const noexcept);\r
+   #endif\r
 private:\r
     //==============================================================================\r
     friend class ComponentPeer;\r
index 984a436f29ba6d11b9c91b787114a1cbb045e87a..133dad4328874777824f2934bf3dac5c590a0f90 100644 (file)
@@ -35,5 +35,6 @@ void MouseListener::mouseDrag (const MouseEvent&)  {}
 void MouseListener::mouseMove (const MouseEvent&)  {}\r
 void MouseListener::mouseDoubleClick (const MouseEvent&) {}\r
 void MouseListener::mouseWheelMove (const MouseEvent&, const MouseWheelDetails&) {}\r
+void MouseListener::mouseMagnify (const MouseEvent&, float) {}\r
 \r
 } // namespace juce\r
index 76160f4c6e2eaae3fb4bce40d94e5df8555c6643..3639db618b080101b43b744099060ab1bbb7c5f5 100644 (file)
@@ -155,6 +155,19 @@ public:
     virtual void mouseWheelMove (const MouseEvent& event,\r
                                  const MouseWheelDetails& wheel);\r
 \r
+    /** Called when a pinch-to-zoom mouse-gesture is used.\r
+\r
+        If not overridden, a component will forward this message to its parent, so\r
+        that parent components can collect gesture messages that are unused by child\r
+        components.\r
+\r
+        @param event   details about the mouse event\r
+        @param scaleFactor  a multiplier to indicate by how much the size of the target\r
+                            should be changed. A value of 1.0 would indicate no change,\r
+                            values greater than 1.0 mean it should be enlarged.\r
+    */\r
+    virtual void mouseMagnify (const MouseEvent& event, float scaleFactor);\r
+\r
 \r
 private:\r
    #if JUCE_CATCH_DEPRECATED_CODE_MISUSE\r
index b4b5f6a2602e0c5e5aba84da90ca9d5062d7376e..662e55e1a8bbedb14f288f7b4950c2ac86cbf98c 100644 (file)
@@ -143,14 +143,17 @@ public:
         auto menuNames = currentModel->getMenuBarNames();\r
         auto indexOfMenu = (int) [superMenu indexOfItemWithSubmenu: menu] - 1;\r
 \r
-        removeItemRecursive (menu);\r
+        if (indexOfMenu >= 0)\r
+        {\r
+            removeItemRecursive (menu);\r
 \r
-        auto updatedPopup = currentModel->getMenuForIndex (indexOfMenu, menuNames[indexOfMenu]);\r
+            auto updatedPopup = currentModel->getMenuForIndex (indexOfMenu, menuNames[indexOfMenu]);\r
 \r
-        for (PopupMenu::MenuItemIterator iter (updatedPopup); iter.next();)\r
-            addMenuItem (iter, menu, 1, indexOfMenu);\r
+            for (PopupMenu::MenuItemIterator iter (updatedPopup); iter.next();)\r
+                addMenuItem (iter, menu, 1, indexOfMenu);\r
 \r
-        [menu update];\r
+            [menu update];\r
+        }\r
     }\r
 \r
     void menuBarItemsChanged (MenuBarModel*) override\r
index 509042ab99091534cd2397aa1afe7adffd369eb9..b33d736effe1336ec6f91e7f560c213cd0cdfd02 100644 (file)
@@ -286,7 +286,7 @@ bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& fi
                     auto eventPos = [event locationInWindow];\r
                     auto dragRect = [view convertRect: NSMakeRect (eventPos.x - 16.0f, eventPos.y - 16.0f, 32.0f, 32.0f)\r
                                              fromView: nil];\r
-                    auto *dragImage = [[NSWorkspace sharedWorkspace] iconForFile: nsFilename];\r
+                    autodragImage = [[NSWorkspace sharedWorkspace] iconForFile: nsFilename];\r
                     [dragItem setDraggingFrame: dragRect\r
                                       contents: dragImage];\r
 \r
index 720c017b825acda2b6ddd0ca913a329b6bb8213e..87515e116dfa38b164dda41d6325f1ad71938bd0 100644 (file)
@@ -802,7 +802,7 @@ struct OnScreenKeyboard   : public DeletedAtShutdown,
         startTimer (10);\r
     }\r
 \r
-    JUCE_DECLARE_SINGLETON_SINGLETHREADED (OnScreenKeyboard, true)\r
+    JUCE_DECLARE_SINGLETON_SINGLETHREADED (OnScreenKeyboard, false)\r
 \r
 private:\r
     OnScreenKeyboard()\r
index 22fa24c94faa7c3d065cb389e127099a37e80cfb..197451488acc14b791050bbaeea28174c5888c61 100644 (file)
@@ -73,7 +73,7 @@ class ChoicePropertyComponent::RemapperValueSourceWithDefault    : public Value:
                                                                    private Value::Listener\r
 {\r
 public:\r
-    RemapperValueSourceWithDefault (const ValueWithDefault& vwd, const Array<var>& map)\r
+    RemapperValueSourceWithDefault (ValueWithDefault& vwd, const Array<var>& map)\r
         : valueWithDefault (vwd),\r
           sourceValue (valueWithDefault.getPropertyAsValue()),\r
           mappings (map)\r
@@ -113,7 +113,7 @@ public:
     }\r
 \r
 private:\r
-    ValueWithDefault valueWithDefault;\r
+    ValueWithDefault& valueWithDefault;\r
     Value sourceValue;\r
     Array<var> mappings;\r
 \r
@@ -155,7 +155,7 @@ ChoicePropertyComponent::ChoicePropertyComponent (const Value& valueToControl,
                                                                              correspondingValues)));\r
 }\r
 \r
-ChoicePropertyComponent::ChoicePropertyComponent (ValueWithDefault valueToControl,\r
+ChoicePropertyComponent::ChoicePropertyComponent (ValueWithDefault& valueToControl,\r
                                                   const String& name,\r
                                                   const StringArray& choiceList,\r
                                                   const Array<var>& correspondingValues)\r
@@ -165,9 +165,19 @@ ChoicePropertyComponent::ChoicePropertyComponent (ValueWithDefault valueToContro
 \r
     comboBox.getSelectedIdAsValue().referTo (Value (new RemapperValueSourceWithDefault (valueToControl,\r
                                                                                         correspondingValues)));\r
+\r
+    valueToControl.onDefaultChange = [this, &valueToControl, choiceList, correspondingValues]\r
+    {\r
+        auto selectedId = comboBox.getSelectedId();\r
+\r
+        comboBox.clear();\r
+        createComboBoxWithDefault (choiceList [correspondingValues.indexOf (valueToControl.getDefault())]);\r
+\r
+        comboBox.setSelectedId (selectedId);\r
+    };\r
 }\r
 \r
-ChoicePropertyComponent::ChoicePropertyComponent (ValueWithDefault valueToControl,\r
+ChoicePropertyComponent::ChoicePropertyComponent (ValueWithDefault& valueToControl,\r
                                                   const String& name)\r
     : PropertyComponent (name),\r
       choices ({ "Enabled", "Disabled" })\r
@@ -176,6 +186,16 @@ ChoicePropertyComponent::ChoicePropertyComponent (ValueWithDefault valueToContro
 \r
     comboBox.getSelectedIdAsValue().referTo (Value (new RemapperValueSourceWithDefault (valueToControl,\r
                                                                                        { true, false })));\r
+\r
+    valueToControl.onDefaultChange = [this, &valueToControl]\r
+    {\r
+        auto selectedId = comboBox.getSelectedId();\r
+\r
+        comboBox.clear();\r
+        createComboBoxWithDefault (valueToControl.getDefault() ? "Enabled" : "Disabled");\r
+\r
+        comboBox.setSelectedId (selectedId);\r
+    };\r
 }\r
 \r
 ChoicePropertyComponent::~ChoicePropertyComponent()\r
index 6cc0c7706cb2f6b67a5ca579f6c629d9effb1cb6..eacbc2cbfc6af32ec1aa6d81f36b08416fff5ae8 100644 (file)
@@ -88,7 +88,7 @@ public:
                                     as the choices array\r
 \r
     */\r
-    ChoicePropertyComponent (ValueWithDefault valueToControl,\r
+    ChoicePropertyComponent (ValueWithDefault& valueToControl,\r
                              const String& propertyName,\r
                              const StringArray& choices,\r
                              const Array<var>& correspondingValues);\r
@@ -98,7 +98,7 @@ public:
 \r
         This is useful for simple on/off choices that also need a default value.\r
     */\r
-    ChoicePropertyComponent (ValueWithDefault valueToControl,\r
+    ChoicePropertyComponent (ValueWithDefault& valueToControl,\r
                              const String& propertyName);\r
 \r
     /** Destructor. */\r
diff --git a/modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp b/modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp
new file mode 100644 (file)
index 0000000..0d1526a
--- /dev/null
@@ -0,0 +1,340 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+\r
+namespace juce\r
+{\r
+\r
+//==============================================================================\r
+class StringComparator\r
+{\r
+public:\r
+    static int compareElements (var first, var second)\r
+    {\r
+        if (first.toString() > second.toString())\r
+            return 1;\r
+        else if (first.toString() < second.toString())\r
+            return -1;\r
+\r
+        return 0;\r
+    }\r
+};\r
+\r
+//==============================================================================\r
+class MultiChoicePropertyComponent::MultiChoiceRemapperSource    : public Value::ValueSource,\r
+                                                                   private Value::Listener\r
+{\r
+public:\r
+    MultiChoiceRemapperSource (const Value& source, var v, int c)\r
+        : sourceValue (source),\r
+          varToControl (v),\r
+          maxChoices (c)\r
+    {\r
+        sourceValue.addListener (this);\r
+    }\r
+\r
+    var getValue() const override\r
+    {\r
+        if (auto* arr = sourceValue.getValue().getArray())\r
+            if (arr->contains (varToControl))\r
+                return true;\r
+\r
+        return false;\r
+    }\r
+\r
+    void setValue (const var& newValue) override\r
+    {\r
+        if (auto* arr = sourceValue.getValue().getArray())\r
+        {\r
+            auto temp = *arr;\r
+\r
+            if (static_cast<bool> (newValue))\r
+            {\r
+                if (temp.addIfNotAlreadyThere (varToControl) && (maxChoices != -1) && (temp.size() > maxChoices))\r
+                     temp.remove (temp.size() - 2);\r
+            }\r
+            else\r
+            {\r
+                temp.remove (arr->indexOf (varToControl));\r
+            }\r
+\r
+            StringComparator c;\r
+            temp.sort (c);\r
+\r
+            sourceValue = temp;\r
+        }\r
+    }\r
+\r
+private:\r
+    Value sourceValue;\r
+    var varToControl;\r
+\r
+    int maxChoices;\r
+\r
+    //==============================================================================\r
+    void valueChanged (Value&) override    { sendChangeMessage (true); }\r
+\r
+    //==============================================================================\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultiChoiceRemapperSource)\r
+};\r
+\r
+//==============================================================================\r
+class MultiChoicePropertyComponent::MultiChoiceRemapperSourceWithDefault    : public Value::ValueSource,\r
+                                                                              private Value::Listener\r
+{\r
+public:\r
+    MultiChoiceRemapperSourceWithDefault (ValueWithDefault& vwd, var v, int c, ToggleButton* b)\r
+        : valueWithDefault (vwd),\r
+          varToControl (v),\r
+          sourceValue (valueWithDefault.getPropertyAsValue()),\r
+          maxChoices (c),\r
+          buttonToControl (b)\r
+    {\r
+        sourceValue.addListener (this);\r
+    }\r
+\r
+    var getValue() const override\r
+    {\r
+        auto v = valueWithDefault.get();\r
+\r
+        if (auto* arr = v.getArray())\r
+        {\r
+            if (arr->contains (varToControl))\r
+            {\r
+                updateButtonTickColour();\r
+                return true;\r
+            }\r
+        }\r
+\r
+        return false;\r
+    }\r
+\r
+    void setValue (const var& newValue) override\r
+    {\r
+        auto v = valueWithDefault.get();\r
+\r
+        OptionalScopedPointer<Array<var>> arrayToControl;\r
+\r
+        if (valueWithDefault.isUsingDefault())\r
+            arrayToControl.set (new Array<var>(), true); // use an empty array so the default values are overwritten\r
+        else\r
+            arrayToControl.set (v.getArray(), false);\r
+\r
+        if (arrayToControl != nullptr)\r
+        {\r
+            auto temp = *arrayToControl;\r
+\r
+            bool newState = newValue;\r
+\r
+            if (valueWithDefault.isUsingDefault())\r
+            {\r
+                if (auto* defaultArray = v.getArray())\r
+                {\r
+                    if (defaultArray->contains (varToControl))\r
+                        newState = true; // force the state as the user is setting it explicitly\r
+                }\r
+            }\r
+\r
+            if (newState)\r
+            {\r
+                if (temp.addIfNotAlreadyThere (varToControl) && (maxChoices != -1) && (temp.size() > maxChoices))\r
+                    temp.remove (temp.size() - 2);\r
+            }\r
+            else\r
+            {\r
+                temp.remove (temp.indexOf (varToControl));\r
+            }\r
+\r
+            StringComparator c;\r
+            temp.sort (c);\r
+\r
+            valueWithDefault = temp;\r
+\r
+            if (temp.size() == 0)\r
+                valueWithDefault.resetToDefault();\r
+        }\r
+    }\r
+\r
+private:\r
+    ValueWithDefault& valueWithDefault;\r
+    var varToControl;\r
+    Value sourceValue;\r
+\r
+    int maxChoices;\r
+\r
+    ToggleButton* buttonToControl;\r
+\r
+    //==============================================================================\r
+    void valueChanged (Value&) override    { sendChangeMessage (true); }\r
+\r
+    void updateButtonTickColour() const noexcept\r
+    {\r
+        auto alpha = valueWithDefault.isUsingDefault() ? 0.4f : 1.0f;\r
+        auto baseColour = buttonToControl->findColour (ToggleButton::tickColourId);\r
+\r
+        buttonToControl->setColour (ToggleButton::tickColourId, baseColour.withAlpha (alpha));\r
+    }\r
+\r
+    //==============================================================================\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultiChoiceRemapperSourceWithDefault)\r
+};\r
+\r
+//==============================================================================\r
+MultiChoicePropertyComponent::MultiChoicePropertyComponent (const String& propertyName,\r
+                                                            const StringArray& choices,\r
+                                                            const Array<var>& correspondingValues)\r
+    : PropertyComponent (propertyName, 70)\r
+{\r
+    // The array of corresponding values must contain one value for each of the items in\r
+    // the choices array!\r
+    jassert (choices.size() == correspondingValues.size());\r
+\r
+    ignoreUnused (correspondingValues);\r
+\r
+    for (auto choice : choices)\r
+        addAndMakeVisible (choiceButtons.add (new ToggleButton (choice)));\r
+\r
+    maxHeight = (choiceButtons.size() * 25) + 20;\r
+\r
+    {\r
+        Path expandShape;\r
+        expandShape.addTriangle ({ 0, 0 }, { 5, 10 }, { 10, 0});\r
+        expandButton.setShape (expandShape, true, true, false);\r
+    }\r
+\r
+    expandButton.onClick = [this] { setExpanded (! expanded); };\r
+    addAndMakeVisible (expandButton);\r
+\r
+    lookAndFeelChanged();\r
+}\r
+\r
+MultiChoicePropertyComponent::MultiChoicePropertyComponent (const Value& valueToControl,\r
+                                                            const String& propertyName,\r
+                                                            const StringArray& choices,\r
+                                                            const Array<var>& correspondingValues,\r
+                                                            int maxChoices)\r
+    : MultiChoicePropertyComponent (propertyName, choices, correspondingValues)\r
+{\r
+    // The value to control must be an array!\r
+    jassert (valueToControl.getValue().isArray());\r
+\r
+    for (int i = 0; i < choiceButtons.size(); ++i)\r
+        choiceButtons[i]->getToggleStateValue().referTo (Value (new MultiChoiceRemapperSource (valueToControl,\r
+                                                                                               correspondingValues[i],\r
+                                                                                               maxChoices)));\r
+}\r
+\r
+MultiChoicePropertyComponent::MultiChoicePropertyComponent (ValueWithDefault& valueToControl,\r
+                                                            const String& propertyName,\r
+                                                            const StringArray& choices,\r
+                                                            const Array<var>& correspondingValues,\r
+                                                            int maxChoices)\r
+    : MultiChoicePropertyComponent (propertyName, choices, correspondingValues)\r
+{\r
+    // The value to control must be an array!\r
+    jassert (valueToControl.get().isArray());\r
+\r
+    for (int i = 0; i < choiceButtons.size(); ++i)\r
+        choiceButtons[i]->getToggleStateValue().referTo (Value (new MultiChoiceRemapperSourceWithDefault (valueToControl,\r
+                                                                                                          correspondingValues[i],\r
+                                                                                                          maxChoices,\r
+                                                                                                          choiceButtons[i])));\r
+\r
+    valueToControl.onDefaultChange = [this] { repaint(); };\r
+}\r
+\r
+void MultiChoicePropertyComponent::paint (Graphics& g)\r
+{\r
+    g.setColour (findColour (TextEditor::backgroundColourId));\r
+    g.fillRect (getLookAndFeel().getPropertyComponentContentPosition (*this));\r
+\r
+    if (! expanded)\r
+    {\r
+        g.setColour (findColour (PropertyComponent::labelTextColourId).withAlpha (0.4f));\r
+        g.drawFittedText ("+ " + String (numHidden) + " more", getLookAndFeel().getPropertyComponentContentPosition (*this)\r
+                                                                               .removeFromBottom (20).withTrimmedLeft (10),\r
+                          Justification::centredLeft, 1);\r
+    }\r
+\r
+    PropertyComponent::paint (g);\r
+}\r
+\r
+void MultiChoicePropertyComponent::resized()\r
+{\r
+    auto bounds = getLookAndFeel().getPropertyComponentContentPosition (*this);\r
+\r
+    bounds.removeFromBottom (5);\r
+\r
+    auto buttonSlice = bounds.removeFromBottom (10);\r
+    expandButton.setSize (10, 10);\r
+    expandButton.setCentrePosition (buttonSlice.getCentre());\r
+\r
+    numHidden = 0;\r
+\r
+    for (auto* b : choiceButtons)\r
+    {\r
+        if (bounds.getHeight() >= 25)\r
+        {\r
+            b->setVisible (true);\r
+            b->setBounds (bounds.removeFromTop (25).reduced (5, 2));\r
+        }\r
+        else\r
+        {\r
+            b->setVisible (false);\r
+            ++numHidden;\r
+        }\r
+    }\r
+}\r
+\r
+void MultiChoicePropertyComponent::setExpanded (bool isExpanded) noexcept\r
+{\r
+    if (expanded == isExpanded)\r
+        return;\r
+\r
+    expanded = isExpanded;\r
+    preferredHeight = expanded ? maxHeight : 70;\r
+\r
+    if (auto* propertyPanel = findParentComponentOfClass<PropertyPanel>())\r
+        propertyPanel->resized();\r
+\r
+    if (onHeightChange != nullptr)\r
+        onHeightChange();\r
+\r
+    expandButton.setTransform (AffineTransform::rotation (expanded ? MathConstants<float>::pi : MathConstants<float>::twoPi,\r
+                                                          (float) expandButton.getBounds().getCentreX(),\r
+                                                          (float) expandButton.getBounds().getCentreY()));\r
+\r
+    resized();\r
+}\r
+\r
+//==============================================================================\r
+void MultiChoicePropertyComponent::lookAndFeelChanged()\r
+{\r
+    auto iconColour = findColour (PropertyComponent::labelTextColourId);\r
+    expandButton.setColours (iconColour, iconColour.darker(), iconColour.darker());\r
+}\r
+\r
+} // namespace juce\r
diff --git a/modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h b/modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h
new file mode 100644 (file)
index 0000000..2a4b3fb
--- /dev/null
@@ -0,0 +1,127 @@
+/*\r
+  ==============================================================================\r
+\r
+   This file is part of the JUCE library.\r
+   Copyright (c) 2017 - ROLI Ltd.\r
+\r
+   JUCE is an open source library subject to commercial or open-source\r
+   licensing.\r
+\r
+   By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+   27th April 2017).\r
+\r
+   End User License Agreement: www.juce.com/juce-5-licence\r
+   Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+   Or: You may also use this code under the terms of the GPL v3 (see\r
+   www.gnu.org/licenses).\r
+\r
+   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+   DISCLAIMED.\r
+\r
+  ==============================================================================\r
+*/\r
+\r
+\r
+namespace juce\r
+{\r
+\r
+//==============================================================================\r
+/**\r
+    A PropertyComponent that shows its value as an expandable list of ToggleButtons.\r
+\r
+    This type of property component contains a list of options where multiple options\r
+    can be selected at once.\r
+\r
+    @see PropertyComponent, PropertyPanel\r
+\r
+    @tags{GUI}\r
+*/\r
+class MultiChoicePropertyComponent    : public PropertyComponent\r
+{\r
+public:\r
+    /** Creates the component. Note that the underlying var object that the Value refers to must be an array.\r
+\r
+        @param valueToControl       the value that the ToggleButtons will read and control\r
+        @param propertyName         the name of the property\r
+        @param choices              the list of possible values that will be represented\r
+        @param correspondingValues  a list of values corresponding to each item in the 'choices' StringArray.\r
+                                    These are the values that will be read and written to the\r
+                                    valueToControl value. This array must contain the same number of items\r
+                                    as the choices array\r
+        @param maxChoices           the maxmimum number of values which can be selected at once. The default of\r
+                                    -1 will not limit the number that can be selected\r
+    */\r
+    MultiChoicePropertyComponent (const Value& valueToControl,\r
+                                  const String& propertyName,\r
+                                  const StringArray& choices,\r
+                                  const Array<var>& correspondingValues,\r
+                                  int maxChoices = -1);\r
+\r
+    /** Creates the component using a ValueWithDefault object. This will select the default options.\r
+\r
+        @param valueToControl       the ValueWithDefault object that contains the Value object that the ToggleButtons will read and control\r
+        @param propertyName         the name of the property\r
+        @param choices              the list of possible values that will be represented\r
+        @param correspondingValues  a list of values corresponding to each item in the 'choices' StringArray.\r
+                                    These are the values that will be read and written to the\r
+                                    valueToControl value. This array must contain the same number of items\r
+                                    as the choices array\r
+        @param maxChoices           the maxmimum number of values which can be selected at once. The default of\r
+                                    -1 will not limit the number that can be selected\r
+    */\r
+    MultiChoicePropertyComponent (ValueWithDefault& valueToControl,\r
+                                  const String& propertyName,\r
+                                  const StringArray& choices,\r
+                                  const Array<var>& correspondingValues,\r
+                                  int maxChoices = -1);\r
+\r
+    //==============================================================================\r
+    /** Returns true if the list of options is expanded. */\r
+    bool isExpanded() const noexcept    { return expanded; }\r
+\r
+    /** Expands or shrinks the list of options.\r
+\r
+        N.B. This will just set the preferredHeight value of the PropertyComponent and attempt to\r
+        call PropertyPanel::resized(), so if you are not displaying this object in a PropertyPanel\r
+        then you should use the onHeightChange callback to resize it when the height changes.\r
+\r
+        @see onHeightChange\r
+    */\r
+    void setExpanded (bool expanded) noexcept;\r
+\r
+    /** You can assign a lambda to this callback object to have it called when the MultiChoicePropertyComponent height changes. */\r
+    std::function<void()> onHeightChange;\r
+\r
+    //==============================================================================\r
+    /** @internal */\r
+    void paint (Graphics& g) override;\r
+    /** @internal */\r
+    void resized() override;\r
+    /** @internal */\r
+    void refresh() override {}\r
+\r
+private:\r
+    MultiChoicePropertyComponent (const String&, const StringArray&, const Array<var>&);\r
+\r
+    class MultiChoiceRemapperSource;\r
+    class MultiChoiceRemapperSourceWithDefault;\r
+\r
+    //==============================================================================\r
+    void lookAndFeelChanged() override;\r
+\r
+    //==============================================================================\r
+    int maxHeight = 0;\r
+    int numHidden = 0;\r
+    bool expanded = false;\r
+\r
+    OwnedArray<ToggleButton> choiceButtons;\r
+    ShapeButton expandButton { "Expand", Colours::transparentBlack, Colours::transparentBlack, Colours::transparentBlack };\r
+\r
+    //==============================================================================\r
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultiChoicePropertyComponent)\r
+};\r
+\r
+} // namespace juce\r
index 81ce960ec5241160c0a7276be5a8ee49f9980124..109b5425db7a60d73365191b9a69b218d02251ec 100644 (file)
@@ -151,11 +151,12 @@ private:
 //==============================================================================\r
 TextPropertyComponent::TextPropertyComponent (const String& name,\r
                                               int maxNumChars,\r
-                                              bool isMultiLine,\r
+                                              bool multiLine,\r
                                               bool isEditable)\r
-    : PropertyComponent (name)\r
+    : PropertyComponent (name),\r
+      isMultiLine (multiLine)\r
 {\r
-    createEditor (maxNumChars, isMultiLine, isEditable);\r
+    createEditor (maxNumChars, isEditable);\r
 }\r
 \r
 TextPropertyComponent::TextPropertyComponent (const Value& valueToControl,\r
@@ -168,7 +169,7 @@ TextPropertyComponent::TextPropertyComponent (const Value& valueToControl,
     textEditor->getTextValue().referTo (valueToControl);\r
 }\r
 \r
-TextPropertyComponent::TextPropertyComponent (const ValueWithDefault& valueToControl,\r
+TextPropertyComponent::TextPropertyComponent (ValueWithDefault& valueToControl,\r
                                               const String& name,\r
                                               int maxNumChars,\r
                                               bool isMultiLine,\r
@@ -177,6 +178,12 @@ TextPropertyComponent::TextPropertyComponent (const ValueWithDefault& valueToCon
 {\r
     textEditor->getTextValue().referTo (Value (new RemapperValueSourceWithDefault (valueToControl)));\r
     textEditor->setTextToDisplayWhenEmpty (valueToControl.getDefault(), 0.5f);\r
+\r
+    valueToControl.onDefaultChange = [this, &valueToControl]\r
+    {\r
+        textEditor->setTextToDisplayWhenEmpty (valueToControl.getDefault(), 0.5f);\r
+        repaint();\r
+    };\r
 }\r
 \r
 TextPropertyComponent::~TextPropertyComponent()\r
@@ -198,7 +205,7 @@ Value& TextPropertyComponent::getValue() const
     return textEditor->getTextValue();\r
 }\r
 \r
-void TextPropertyComponent::createEditor (int maxNumChars, bool isMultiLine, bool isEditable)\r
+void TextPropertyComponent::createEditor (int maxNumChars, bool isEditable)\r
 {\r
     textEditor.reset (new LabelComp (*this, maxNumChars, isMultiLine, isEditable));\r
     addAndMakeVisible (textEditor.get());\r
index 8d42d34578f7e695cdc47e3bdcaad44a23ac0ccf..54a03a8d57036c3daa39dc08d9d4f411befd1429 100644 (file)
@@ -83,7 +83,7 @@ public:
 \r
         @see TextEditor, setEditable\r
     */\r
-    TextPropertyComponent (const ValueWithDefault& valueToControl,\r
+    TextPropertyComponent (ValueWithDefault& valueToControl,\r
                            const String& propertyName,\r
                            int maxNumChars,\r
                            bool isMultiLine,\r
@@ -106,6 +106,10 @@ public:
     /** Returns the text that should be shown in the text editor as a Value object. */\r
     Value& getValue() const;\r
 \r
+    //==============================================================================\r
+    /** Returns true if the text editor allows carriage returns. */\r
+    bool isTextEditorMultiLine() const noexcept    { return isMultiLine; }\r
+\r
     //==============================================================================\r
     /** A set of colour IDs to use to change the colour of various aspects of the component.\r
 \r
@@ -164,6 +168,8 @@ public:
     virtual void textWasEdited();\r
 \r
 private:\r
+    bool isMultiLine;\r
+\r
     class RemapperValueSourceWithDefault;\r
 \r
     class LabelComp;\r
@@ -173,7 +179,7 @@ private:
     ListenerList<Listener> listenerList;\r
 \r
     void callListeners();\r
-    void createEditor (int maxNumChars, bool isMultiLine, bool isEditable);\r
+    void createEditor (int maxNumChars, bool isEditable);\r
 \r
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextPropertyComponent)\r
 };\r
index 409991dbb4f08c564e3e9ff63aedb23d83375416..20fa4332399bdac6f89f81d00be38de9e453a757 100644 (file)
@@ -1240,6 +1240,16 @@ void TextEditor::removeListener (Listener* l)   { listeners.remove (l); }
 \r
 //==============================================================================\r
 void TextEditor::timerCallbackInt()\r
+{\r
+    checkFocus();\r
+\r
+    auto now = Time::getApproximateMillisecondCounter();\r
+\r
+    if (now > lastTransactionTime + 200)\r
+        newTransaction();\r
+}\r
+\r
+void TextEditor::checkFocus()\r
 {\r
     if (hasKeyboardFocus (false) && ! isCurrentlyBlockedByAnotherModalComponent())\r
     {\r
@@ -1249,11 +1259,6 @@ void TextEditor::timerCallbackInt()
             if (! isReadOnly())\r
                 peer->textInputRequired (peer->globalToLocal (getScreenPosition()), *this);\r
     }\r
-\r
-    auto now = Time::getApproximateMillisecondCounter();\r
-\r
-    if (now > lastTransactionTime + 200)\r
-        newTransaction();\r
 }\r
 \r
 void TextEditor::repaintText (Range<int> range)\r
@@ -2066,6 +2071,12 @@ void TextEditor::focusGained (FocusChangeType)
         moveCaretTo (getTotalNumChars(), true);\r
     }\r
 \r
+    // When caret position changes, we check focus automatically, to\r
+    // show any native keyboard if needed. If the position does not\r
+    // change though, we need to check focus manually.\r
+    if (getTotalNumChars() == 0)\r
+        checkFocus();\r
+\r
     repaint();\r
     updateCaretPosition();\r
 }\r
index 60f348fdcf4e32058d979c38b26d539336af1c90..517f1884390f9f60939ca8bed097dfb2782cf439 100644 (file)
@@ -777,6 +777,7 @@ private:
     float getWordWrapWidth() const;\r
     float getJustificationWidth() const;\r
     void timerCallbackInt();\r
+    void checkFocus();\r
     void repaintText (Range<int>);\r
     void scrollByLines (int deltaLines);\r
     bool undoOrRedo (bool shouldUndo);\r
index 3426cb662514213750d5d58ba475e4be1859322e..a4a94194e2b06654f7e00217f0a68222759b08db 100644 (file)
@@ -58,6 +58,16 @@ AlertWindow::AlertWindow (const String& title,
 \r
 AlertWindow::~AlertWindow()\r
 {\r
+    // Ensure that the focus does not jump to another TextEditor while we\r
+    // remove children.\r
+    for (auto* t : textBoxes)\r
+        t->setWantsKeyboardFocus (false);\r
+\r
+    // Giveaway focus before removing the editors, so that any TextEditor\r
+    // with focus has a chance to dismiss native keyboard if shown.\r
+    if (hasKeyboardFocus (true))\r
+        Component::unfocusAllComponents();\r
+\r
     removeAllChildren();\r
 }\r
 \r
index 444d210f2e110438232e3a916a9c2b7e2a65c335..c58ebf62cbca71a13c4aa952dfca381c8fa8c92e 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_gui_extra\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE extended GUI classes\r
   description:      Miscellaneous GUI classes for specialised tasks.\r
   website:          http://www.juce.com/juce\r
index 129cafdf5f498d38610b678987e0ee7f2abb9718..3f6825db8d2ec468448047703169db10e7b3912d 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_opengl\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE OpenGL classes\r
   description:      Classes for rendering OpenGL in a JUCE window.\r
   website:          http://www.juce.com/juce\r
index 7c89c8704e6f7066dc73479cb29d45883d72e652..3acfe178a6b0618f77fb9c19ef1db17c5881cfbc 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_osc\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE OSC classes\r
   description:      Open Sound Control implementation.\r
   website:          http://www.juce.com/juce\r
index b941117a9952dfa60bdc7d6fadea504245a5c494..25237e79354f202a62e80b0b9ae7e0bdef57ff82 100644 (file)
@@ -35,7 +35,7 @@
 \r
   ID:               juce_product_unlocking\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE Online marketplace support\r
   description:      Classes for online product authentication\r
   website:          http://www.juce.com/juce\r
index e799615e4300b1ef1500bb6d201a893d11a75ec5..4333e43db431dbf4cb86aa0f74ca342b6523baf7 100644 (file)
@@ -36,7 +36,7 @@
 \r
   ID:               juce_video\r
   vendor:           juce\r
-  version:          5.3.0\r
+  version:          5.3.1\r
   name:             JUCE video playback and capture classes\r
   description:      Classes for playing video and capturing camera input.\r
   website:          http://www.juce.com/juce\r