\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
\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
\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
\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
\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
\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
\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
\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
\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
\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
pairButton.setEnabled (false);\r
\r
addAndMakeVisible (pairButton);\r
- pairButton.onClick = [this]\r
+ pairButton.onClick = []\r
{\r
RuntimePermissions::request (RuntimePermissions::bluetoothMidi,\r
[] (bool wasGranted)\r
}\r
\r
//==============================================================================\r
- void paintListBoxItem (int rowNumber, Graphics &g,\r
+ void paintListBoxItem (int rowNumber, Graphics& g,\r
int width, int height, bool rowIsSelected) override\r
{\r
auto textColour = getLookAndFeel().findColour (ListBox::textColourId);\r
};\r
\r
//==============================================================================\r
- void handleIncomingMidiMessage (MidiInput* /*source*/, const MidiMessage &message) override\r
+ void handleIncomingMidiMessage (MidiInput* /*source*/, const MidiMessage& message) override\r
{\r
// This is called on the MIDI thread\r
\r
\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
// 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
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
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
{\r
memcpy (channelData,\r
bufferToFill.buffer->getReadPointer (0),\r
- bufferToFill.numSamples * sizeof (float));\r
+ ((size_t) bufferToFill.numSamples) * sizeof (float));\r
}\r
}\r
}\r
\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
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
\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
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
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
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
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
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
return xPos == x && yPos == y;\r
}\r
};\r
+\r
Array<ActiveLED> activeLeds;\r
\r
int getLEDAt (uint32 x, uint32 y) const\r
colourPalette = 0,\r
canvas\r
};\r
+\r
DisplayMode currentMode = colourPalette;\r
\r
//==============================================================================\r
\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
\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
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
\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
*/\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
*/\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
#endif\r
\r
setSize (600, 400);\r
- };\r
+ }\r
\r
~BlocksSynthDemo()\r
{\r
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
PhysicalTopologySource topologySource;\r
Block::Ptr activeBlock;\r
\r
- Array<juce::Time> touchMessageTimesInLastSecond;\r
+ Array<Time> touchMessageTimesInLastSecond;\r
\r
int waveshapeMode = 0;\r
\r
\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
\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
\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
\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
\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
\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
\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
\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
\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
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
"../../../../../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_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_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
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_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_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
\r
android {\r
compileSdkVersion 23\r
- buildToolsVersion "27.0.0"\r
+ buildToolsVersion "27.0.3"\r
externalNativeBuild {\r
cmake {\r
path "CMakeLists.txt"\r
<?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"/>
\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
\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
\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
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
-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
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
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
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;
}
<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
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
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
</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
<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
<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
#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
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
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
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
</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
<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
<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
#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
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
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
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
</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
<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
<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
#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
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
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;
}
<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
<?xml version="1.0" encoding="UTF-8"?>\r
\r
-<JUCERPROJECT name="DemoRunner" projectType="guiapp" jucerVersion="5.3.0" defines="JUCE_DEMO_RUNNER=1 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 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
</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
//#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
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
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
\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
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
codeEditor.setScrollbarThickness (8);\r
\r
lookAndFeelChanged();\r
- };\r
+ }\r
\r
void resized() override\r
{\r
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
&& (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
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
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
\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
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
{\r
if (renderingEngineIndex == (renderingEngines.size() - 1))\r
{\r
+ if (isShowingHeavyweightDemo)\r
+ return;\r
+\r
openGLContext.attachTo (*getTopLevelComponent());\r
}\r
else\r
#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
\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
\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
\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
\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
\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
\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
\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
\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
\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
\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
\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
\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
\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
\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
\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
\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
\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
\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
\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
\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
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
"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
{\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
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
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
\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
\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
\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
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
\r
{\r
auto* panel = new PropertyPanel ("Choice Properties");\r
- panel->addProperties (createChoices (12));\r
+ panel->addProperties (createChoices (3));\r
addPanel (panel);\r
}\r
\r
addPanel (panel);\r
}\r
\r
+\r
+ setSize (750, 650);\r
startTimer (300);\r
}\r
\r
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
\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
\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
\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
\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
\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
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
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
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
\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
\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
\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
\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
//==============================================================================\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
\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
\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
\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
\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
synth[midiChannel]->addVoice (new SamplerVoice());\r
}\r
\r
- loadNewSample (getAssetsDirectory().getChildFile ("singing.ogg"));\r
+ loadNewSample (createAssetInputStream ("singing.ogg"), "ogg");\r
}\r
\r
~MultiOutSynth() {}\r
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
\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
\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
#include <iomanip>\r
#include <sstream>\r
#include <functional>\r
+#include <mutex>\r
\r
namespace IDs\r
{\r
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
}\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
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
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
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
// 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
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
};\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
{\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
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
: 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
{\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
}\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
{\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
}\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
{\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
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
\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
}\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
\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
\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
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
/ 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
visibleRange.setVisibleRange (range, nullptr);\r
}\r
\r
- void visibleRangeChanged (Range<double> value) override\r
+ void visibleRangeChanged (Range<double>) override\r
{\r
repaint();\r
}\r
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
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
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
\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
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
{\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
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
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
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
// 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
}\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
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
}\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
{\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
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
};\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
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
\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
\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
\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
\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
\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
\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
\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
//==============================================================================\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
\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
\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
\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
\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
\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
\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
\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
\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
setWantsKeyboardFocus (true);\r
}\r
\r
- void addRowComponent (RowComponent *rc)\r
+ void addRowComponent (RowComponent* rc)\r
{\r
rowComponents.add (rc);\r
addAndMakeVisible (rc);\r
{\r
auto totalRowUnits = 0;\r
\r
- for (auto &rc : rowComponents)\r
+ for (auto* rc : rowComponents)\r
totalRowUnits += rc->rowUnits;\r
\r
auto rowHeight = getHeight() / totalRowUnits;\r
\r
auto bounds = getLocalBounds();\r
\r
- for (auto &rc : rowComponents)\r
+ for (auto* rc : rowComponents)\r
rc->setBounds (bounds.removeFromTop (rc->rowUnits * rowHeight));\r
\r
auto* last = rowComponents[rowComponents.size() - 1];\r
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
\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
pendingNotifIdentifier .setBounds (rowBounds);\r
\r
removeAllPendingNotifsButton .setBounds (bounds.removeFromTop (rowHeight));\r
- #endif\r
+ #endif\r
}\r
\r
TextButton getDeliveredNotificationsButton { "Get Delivered Notifications" };\r
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
if (! showedRemoteInstructions && newCurrentTabName == "Remote")\r
{\r
PushNotificationsDemo::showRemoteInstructions();\r
-\r
showedRemoteInstructions = true;\r
}\r
-\r
}\r
\r
private:\r
\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
+++ /dev/null
-/*\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
\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
\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
\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
\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
\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
<?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
"../../../../../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_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_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
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_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_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
\r
android {\r
compileSdkVersion 23\r
- buildToolsVersion "27.0.0"\r
+ buildToolsVersion "27.0.3"\r
externalNativeBuild {\r
cmake {\r
path "CMakeLists.txt"\r
\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
\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
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
-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
<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
<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
//#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
\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
<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
<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
<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
--- /dev/null
+# 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
--- /dev/null
+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
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<resources>
+ <string name="app_name">AudioPluginHost</string>
+</resources>
--- /dev/null
+<?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>
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ 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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ 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
--- /dev/null
+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
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<resources>
+ <string name="app_name">AudioPluginHost</string>
+</resources>
--- /dev/null
+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
--- /dev/null
+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.
+
--- /dev/null
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
\ No newline at end of file
--- /dev/null
+#!/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 "$@"
--- /dev/null
+@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
--- /dev/null
+include ':app'
\ No newline at end of file
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
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
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
-$(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
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,
<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
<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
\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
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
<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
\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
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
<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
\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
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
--- /dev/null
+// !$*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;
+}
--- /dev/null
+{\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
--- /dev/null
+{\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
--- /dev/null
+<?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
//==============================================================================\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
--- /dev/null
+/* ==================================== 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
--- /dev/null
+/* =========================================================================================\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
#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
+++ /dev/null
-/*\r
- ==============================================================================\r
-\r
- This file is part of the JUCE library.\r
- Copyright (c) 2017 - ROLI Ltd.\r
-\r
- JUCE is an open source library subject to commercial or open-source\r
- licensing.\r
-\r
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
- 27th April 2017).\r
-\r
- End User License Agreement: www.juce.com/juce-5-licence\r
- Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
- Or: You may also use this code under the terms of the GPL v3 (see\r
- www.gnu.org/licenses).\r
-\r
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
- DISCLAIMED.\r
-\r
- ==============================================================================\r
-*/\r
-\r
-#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
+++ /dev/null
-/*\r
- ==============================================================================\r
-\r
- This file is part of the JUCE library.\r
- Copyright (c) 2017 - ROLI Ltd.\r
-\r
- JUCE is an open source library subject to commercial or open-source\r
- licensing.\r
-\r
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
- 27th April 2017).\r
-\r
- End User License Agreement: www.juce.com/juce-5-licence\r
- Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
- Or: You may also use this code under the terms of the GPL v3 (see\r
- www.gnu.org/licenses).\r
-\r
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
- DISCLAIMED.\r
-\r
- ==============================================================================\r
-*/\r
-\r
-#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
+++ /dev/null
-/*\r
- ==============================================================================\r
-\r
- This file is part of the JUCE library.\r
- Copyright (c) 2017 - ROLI Ltd.\r
-\r
- JUCE is an open source library subject to commercial or open-source\r
- licensing.\r
-\r
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
- 27th April 2017).\r
-\r
- End User License Agreement: www.juce.com/juce-5-licence\r
- Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
- Or: You may also use this code under the terms of the GPL v3 (see\r
- www.gnu.org/licenses).\r
-\r
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
- DISCLAIMED.\r
-\r
- ==============================================================================\r
-*/\r
-\r
-#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
+++ /dev/null
-/*\r
- ==============================================================================\r
-\r
- This file is part of the JUCE library.\r
- Copyright (c) 2017 - ROLI Ltd.\r
-\r
- JUCE is an open source library subject to commercial or open-source\r
- licensing.\r
-\r
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
- 27th April 2017).\r
-\r
- End User License Agreement: www.juce.com/juce-5-licence\r
- Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
- Or: You may also use this code under the terms of the GPL v3 (see\r
- www.gnu.org/licenses).\r
-\r
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
- DISCLAIMED.\r
-\r
- ==============================================================================\r
-*/\r
-\r
-#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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
+++ /dev/null
-/*\r
- ==============================================================================\r
-\r
- This file is part of the JUCE library.\r
- Copyright (c) 2017 - ROLI Ltd.\r
-\r
- JUCE is an open source library subject to commercial or open-source\r
- licensing.\r
-\r
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
- 27th April 2017).\r
-\r
- End User License Agreement: www.juce.com/juce-5-licence\r
- Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
- Or: You may also use this code under the terms of the GPL v3 (see\r
- www.gnu.org/licenses).\r
-\r
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
- DISCLAIMED.\r
-\r
- ==============================================================================\r
-*/\r
-\r
-#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
+++ /dev/null
-/*\r
- ==============================================================================\r
-\r
- This file is part of the JUCE library.\r
- Copyright (c) 2017 - ROLI Ltd.\r
-\r
- JUCE is an open source library subject to commercial or open-source\r
- licensing.\r
-\r
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
- 27th April 2017).\r
-\r
- End User License Agreement: www.juce.com/juce-5-licence\r
- Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
- Or: You may also use this code under the terms of the GPL v3 (see\r
- www.gnu.org/licenses).\r
-\r
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
- DISCLAIMED.\r
-\r
- ==============================================================================\r
-*/\r
-\r
-#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
*/\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
{\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
if (fileToOpen.existsAsFile())\r
break;\r
}\r
+ #endif\r
\r
if (! fileToOpen.existsAsFile())\r
{\r
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
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
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
+++ /dev/null
-/*\r
- ==============================================================================\r
-\r
- This file is part of the JUCE library.\r
- Copyright (c) 2017 - ROLI Ltd.\r
-\r
- JUCE is an open source library subject to commercial or open-source\r
- licensing.\r
-\r
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
- 27th April 2017).\r
-\r
- End User License Agreement: www.juce.com/juce-5-licence\r
- Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
- Or: You may also use this code under the terms of the GPL v3 (see\r
- www.gnu.org/licenses).\r
-\r
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
- DISCLAIMED.\r
-\r
- ==============================================================================\r
-*/\r
-\r
-#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
+++ /dev/null
-/*\r
- ==============================================================================\r
-\r
- This file is part of the JUCE library.\r
- Copyright (c) 2017 - ROLI Ltd.\r
-\r
- JUCE is an open source library subject to commercial or open-source\r
- licensing.\r
-\r
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
- 27th April 2017).\r
-\r
- End User License Agreement: www.juce.com/juce-5-licence\r
- Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
- Or: You may also use this code under the terms of the GPL v3 (see\r
- www.gnu.org/licenses).\r
-\r
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
- DISCLAIMED.\r
-\r
- ==============================================================================\r
-*/\r
-\r
-#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
+++ /dev/null
-/*\r
- ==============================================================================\r
-\r
- This file is part of the JUCE library.\r
- Copyright (c) 2017 - ROLI Ltd.\r
-\r
- JUCE is an open source library subject to commercial or open-source\r
- licensing.\r
-\r
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
- 27th April 2017).\r
-\r
- End User License Agreement: www.juce.com/juce-5-licence\r
- Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
- Or: You may also use this code under the terms of the GPL v3 (see\r
- www.gnu.org/licenses).\r
-\r
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
- DISCLAIMED.\r
-\r
- ==============================================================================\r
-*/\r
-\r
-#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
+++ /dev/null
-/*\r
- ==============================================================================\r
-\r
- This file is part of the JUCE library.\r
- Copyright (c) 2017 - ROLI Ltd.\r
-\r
- JUCE is an open source library subject to commercial or open-source\r
- licensing.\r
-\r
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
- 27th April 2017).\r
-\r
- End User License Agreement: www.juce.com/juce-5-licence\r
- Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
- Or: You may also use this code under the terms of the GPL v3 (see\r
- www.gnu.org/licenses).\r
-\r
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
- DISCLAIMED.\r
-\r
- ==============================================================================\r
-*/\r
-\r
-#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
+++ /dev/null
-/*\r
- ==============================================================================\r
-\r
- This file is part of the JUCE library.\r
- Copyright (c) 2017 - ROLI Ltd.\r
-\r
- JUCE is an open source library subject to commercial or open-source\r
- licensing.\r
-\r
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
- 27th April 2017).\r
-\r
- End User License Agreement: www.juce.com/juce-5-licence\r
- Privacy Policy: www.juce.com/juce-5-privacy-policy\r
-\r
- Or: You may also use this code under the terms of the GPL v3 (see\r
- www.gnu.org/licenses).\r
-\r
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
- DISCLAIMED.\r
-\r
- ==============================================================================\r
-*/\r
-\r
-#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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
+++ /dev/null
-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
-
+++ /dev/null
-<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>
+++ /dev/null
-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
+++ /dev/null
-<hr class="footer"/>
-<address class="footer"><small>All content © ROLI Ltd.</small></address><br/>
-</body>
-</html>
+++ /dev/null
-<!-- 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--> <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 -->
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-/**\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
+++ /dev/null
-@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;
-}
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
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
#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
/*\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
{\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
/*\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
/*\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
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
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
/*\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
/*\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
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
<?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
"../../../../../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_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_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
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_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_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
\r
android {\r
compileSdkVersion 10\r
- buildToolsVersion "27.0.0"\r
+ buildToolsVersion "27.0.3"\r
externalNativeBuild {\r
cmake {\r
path "CMakeLists.txt"\r
\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
\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
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
-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
<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
<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
<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
<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
//#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
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
}\r
\r
numBytes = 0;\r
- return 0;\r
+ return nullptr;\r
}\r
\r
const char* namedResourceList[] =\r
"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
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
<?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
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
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
<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
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",
<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
<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
#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
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
<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
<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
#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
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
<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
<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
#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
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
\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
" 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
"\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
"%%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=\"<Monospaced>; 13.0\">\r\n"\r
" <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=\"<Monospaced>; 13.0\">\r\n"\r
" <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
" </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
"\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
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
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
}\r
\r
numBytes = 0;\r
- return 0;\r
+ return nullptr;\r
}\r
\r
const char* namedResourceList[] =\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
"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
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
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
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
<?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
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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
{\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
}\r
}\r
\r
-Array<File> ProjucerApplication::getSortedExampleDirectories() const noexcept\r
+Array<File> ProjucerApplication::getSortedExampleDirectories() noexcept\r
{\r
Array<File> exampleDirectories;\r
\r
{\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
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
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
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
\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
\r
const CommandID ids[] = { CommandIDs::newProject,\r
CommandIDs::newProjectFromClipboard,\r
+ CommandIDs::newPIP,\r
CommandIDs::open,\r
CommandIDs::launchDemoRunner,\r
CommandIDs::closeAllWindows,\r
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
{\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
}\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
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
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
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
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
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
\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
\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
\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
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
#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
//==============================================================================\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
void showPathsWindow (bool highlightJUCEPath = false);\r
void showEditorColourSchemeWindow();\r
\r
+ void showPIPCreatorWindow();\r
+\r
void launchForumBrowser();\r
void launchModulesBrowser();\r
void launchClassesBrowser();\r
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
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
{\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
\r
#include "jucer_CommandLine.h"\r
\r
+//==============================================================================\r
+const char* preferredLinefeed = "\r\n";\r
+const char* getPreferredLinefeed() { return preferredLinefeed; }\r
\r
//==============================================================================\r
namespace\r
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
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
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
\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
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
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
\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
\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
<< 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
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
#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
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
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
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
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
void createProjectContentCompIfNeeded();\r
void setTitleBarIcon();\r
\r
- void openPIP (PIPGenerator&, StringRef fileName);\r
+ void openPIP (PIPGenerator&);\r
\r
void valueChanged (Value&) override;\r
\r
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
appEvent,\r
projectEvent,\r
userEvent,\r
- exampleEvent\r
+ exampleEvent,\r
+ startPageEvent\r
};\r
\r
//==============================================================================\r
--- /dev/null
+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
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
\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
--- /dev/null
+/*******************************************************************************\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
\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
#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
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
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
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
}\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
\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
\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
{\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
\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
\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
{\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
\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
\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
\r
void timerCallback() override\r
{\r
- if (owner.continuousRebuild)\r
+ if (owner.project.getCompileEngineSettings().isContinuousRebuildEnabled())\r
flushEditorChanges();\r
else\r
stopTimer();\r
}\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
\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
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
class ChildProcess;\r
ScopedPointer<ChildProcess> process, runningAppProcess;\r
ClassDatabase::ClassList lastComponentList;\r
- bool continuousRebuild;\r
\r
struct Editor;\r
OwnedArray<Editor> editors;\r
\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
}\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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+#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
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
\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
String moduleID;\r
Value globalPathValue;\r
Value defaultJuceModulePathValue, defaultUserModulePathValue;\r
+ OwnedArray <Project::ConfigFlag> configFlags;\r
\r
ReferenceCountedArray<Value::ValueSource> modulePathValueSources;\r
\r
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
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
void handlePopupMenuResult (int resultCode) override\r
{\r
auto& modules = project.getModules();\r
- auto numModulesBefore = modules.getNumModules();\r
\r
if (resultCode == 1001)\r
{\r
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
\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
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
\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
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
}\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
if (! displayError)\r
lastCrashMessage = {};\r
\r
- LiveBuildProjectSettings::setBuildDisabled (*project, ! isEnabled);\r
+ project->getCompileEngineSettings().setBuildEnabled (isEnabled);\r
killChildProcess();\r
refreshTabsIfBuildStatusChanged();\r
\r
\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
\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
{\r
if (project != nullptr)\r
{\r
- LiveBuildProjectSettings::setWarningsDisabled (*project, areWarningsEnabled());\r
+ project->getCompileEngineSettings().setWarningsEnabled (! areWarningsEnabled());\r
updateWarningState();\r
}\r
}\r
\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
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
.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
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
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
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
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
//==============================================================================\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
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
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
initialiseMainGroup();\r
initialiseAudioPluginValues();\r
\r
+ coalescePluginFormatValues();\r
+ coalescePluginCharacteristicsValues();\r
+ updatePluginCategories();\r
+\r
parsedPreprocessorDefs = parsePreprocessorDefs (preprocessorDefsValue.get());\r
\r
removeDefunctExporters();\r
}\r
else if (property == Ids::name)\r
{\r
- setTitle (projectRoot [Ids::name]);\r
+ updateTitle();\r
}\r
else if (property == Ids::defines)\r
{\r
{\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
"(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
\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
}\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
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
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
#pragma once\r
\r
#include "jucer_ProjectType.h"\r
+#include "../LiveBuildEngine/jucer_CompileEngineSettings.h"\r
\r
class ProjectExporter;\r
class LibraryModule;\r
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
\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
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
//==============================================================================\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
void createAudioPluginPropertyEditors (PropertyListBuilder& props);\r
\r
//==============================================================================\r
+ void updateTitle();\r
void updateProjectSettings();\r
ValueTree getConfigurations() const;\r
ValueTree getConfigNode();\r
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
\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
mo << "" << newLine;\r
mo << "allprojects {" << newLine;\r
mo << " repositories {" << newLine;\r
+ mo << " google()" << newLine;\r
mo << " jcenter()" << newLine;\r
\r
if (androidEnableRemoteNotifications.get())\r
{\r
name = getName();\r
\r
- targetLocationValue.setDefault (getDefaultBuildsRootFolder() + "CLion");\r
+ targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderForExporter (getValueTreeTypeName()));\r
}\r
\r
//==============================================================================\r
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
{\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
}\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
case pluginBundle:\r
switch (type)\r
{\r
- case VST3PlugIn: return ".vst3";\r
case VSTPlugIn: return ".so";\r
default: break;\r
}\r
\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
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
\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
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
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
{\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
{\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
{\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
{\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
{\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
{\r
name = getNameLinux();\r
\r
- targetLocationValue.setDefault (getDefaultBuildsRootFolder() + "LinuxMakefile");\r
+ targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderForExporter (getValueTreeTypeName()));\r
}\r
\r
//==============================================================================\r
}\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
{\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
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
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
}\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
}\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
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
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
\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
\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
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
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
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
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
};\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
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
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
\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
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
}\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
\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
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
#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
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
\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
}\r
\r
//==============================================================================\r
-bool isJUCEModule (const String& moduleID) noexcept\r
+StringArray getJUCEModules() noexcept\r
{\r
static StringArray juceModuleIds =\r
{\r
"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
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
\r
\r
//==============================================================================\r
-const char* getLineEnding();\r
+const char* getPreferredLinefeed();\r
String joinLinesIntoSourceFile (StringArray& lines);\r
\r
String trimCommentCharsFromStartOfLine (const String& line);\r
\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
\r
bool isPIPFile (const File&) noexcept;\r
\r
-File getJUCEExamplesDirectoryPathFromGlobal() noexcept;\r
bool isValidJUCEExamplesDirectory (const File&) noexcept;\r
\r
//==============================================================================\r
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
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
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
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
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
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
*/\r
\r
#include "../../Application/jucer_Headers.h"\r
+#include "../../ProjectSaving/jucer_ProjectExporter.h"\r
#include "jucer_PIPGenerator.h"\r
\r
//==============================================================================\r
}\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
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
{\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
\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
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
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
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
//==============================================================================\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
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
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
TreeViewItem::paintOpenCloseButton (g, area, getOwnerView()->findColour (defaultIconColourId), isMouseOver);\r
}\r
\r
-void JucerTreeViewBase::paintIcon (Graphics &g, Rectangle<float> area)\r
+void JucerTreeViewBase::paintIcon (Graphics& g, Rectangle<float> area)\r
{\r
g.setColour (getContentColour (true));\r
getIcon().draw (g, area, isIconCrossedOut());\r
\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
}\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
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; };
<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
<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
//#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
<?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
</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
<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
<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
//#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
<?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
\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
\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
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
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
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
\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
{\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
}\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
namespace juce\r
{\r
\r
-#if JUCE_MAC || JUCE_IOS && ! DOXYGEN\r
+#if ! DOXYGEN && (JUCE_MAC || JUCE_IOS)\r
\r
struct CoreAudioLayouts\r
{\r
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
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
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
*/\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
\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
class ALSAAudioIODeviceType : public AudioIODeviceType\r
{\r
public:\r
- ALSAAudioIODeviceType (bool onlySoundcards, const String &deviceTypeName)\r
+ ALSAAudioIODeviceType (bool onlySoundcards, const String& deviceTypeName)\r
: AudioIODeviceType (deviceTypeName),\r
- hasScanned (false),\r
listOnlySoundcards (onlySoundcards)\r
{\r
#if ! JUCE_ALSA_LOGGING\r
{\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
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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ 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
//==============================================================================\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
\r
if (activeHandle->deviceId == deviceId)\r
{\r
- activeHandle->refCount++;\r
han = activeHandle;\r
return;\r
}\r
\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
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
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
//==============================================================================\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
\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
#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
#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
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
{\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
\r
if (pluginEditor != nullptr)\r
{\r
- setBounds (pluginEditor->getLocalBounds());\r
+ lastValidSize = pluginEditor->getLocalBounds();\r
+ setBounds (lastValidSize);\r
pluginEditor->addMouseListener (this, true);\r
}\r
\r
{\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
WindowsHooks hooks;\r
#endif\r
FakeMouseMoveGenerator fakeMouseGenerator;\r
+ juce::Rectangle<int> lastValidSize;\r
\r
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentWrapperComponent)\r
};\r
AAX_Result Uninitialize() override\r
{\r
cancelPendingUpdate();\r
+ juceParameters.clear();\r
\r
if (isPrepared && pluginInstance != nullptr)\r
{\r
if (err != AAX_SUCCESS)\r
return err;\r
\r
- addBypassParameter();\r
addAudioProcessorParameters();\r
\r
return AAX_SUCCESS;\r
// * 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
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
\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
{\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
\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
#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
//==============================================================================\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
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
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
//==============================================================================\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
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
#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
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
: 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
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
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
//==============================================================================\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
\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
\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
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
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
\r
void childBoundsChanged (Component*) override\r
{\r
- updateWindowSize();\r
+ updateWindowSize (false);\r
}\r
\r
juce::Rectangle<int> getSizeToContainChild()\r
return {};\r
}\r
\r
- void updateWindowSize()\r
+ void updateWindowSize (bool resizeEditor)\r
{\r
if (! isInSizeWindow)\r
{\r
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
JuceVSTWrapper& wrapper;\r
FakeMouseMoveGenerator fakeMouseGenerator;\r
bool isInSizeWindow = false;\r
+ bool shouldResizeEditor = true;\r
\r
#if JUCE_MAC\r
void* hostWindow = {};\r
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
\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
\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
\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
\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
\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
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
ed->setScaleFactor (editorScaleFactor);\r
\r
if (editorComp != nullptr)\r
- editorComp->updateWindowSize();\r
+ editorComp->updateWindowSize (true);\r
}\r
#endif\r
}\r
{\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
#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
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
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
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
{\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
\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 (¶m))\r
{\r
- outValueNormalized = p->getValueForText (getStringFromVstTChars (text));\r
+ outValueNormalized = param.getValueForText (getStringFromVstTChars (text));\r
return true;\r
}\r
\r
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
// 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
}\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
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
\r
private:\r
friend class JuceVST3Component;\r
+ friend struct Param;\r
\r
//==============================================================================\r
ComSmartPtr<JuceAudioProcessor> audioProcessor;\r
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
}\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
: 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
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
\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
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
{\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
&& 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
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
#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
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
\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
#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
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
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
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
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
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
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
}\r
}\r
\r
- // called from the destructer above\r
+ // called from the destructor above\r
void cleanup()\r
{\r
#if JUCE_MAC\r
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
}\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
}\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
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
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
MidiDataConcatenator midiConcatenator;\r
CriticalSection midiInLock;\r
MidiBuffer incomingMidi;\r
+ ScopedPointer<AUBypassParameter> bypassParam;\r
+ bool lastProcessBlockCallWasBypass = false, auSupportsBypass = false;\r
\r
void createPluginCallbacks()\r
{\r
addPropertyChangeListener (kAudioUnitProperty_PresentPreset);\r
addPropertyChangeListener (kAudioUnitProperty_ParameterList);\r
addPropertyChangeListener (kAudioUnitProperty_Latency);\r
+ addPropertyChangeListener (kAudioUnitProperty_BypassEffect);\r
#endif\r
}\r
}\r
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
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
#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
{\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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+namespace juce\r
+{\r
+\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
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
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
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
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
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
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
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
: 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
valueType));\r
}\r
\r
+ vstSupportsBypass = pluginCanDo ("bypass");\r
setRateAndBufferSizeDetails (sampleRateToUse, blockSizeToUse);\r
}\r
\r
}\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
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
\r
AudioBuffer<double> tmpBufferDouble;\r
HeapBlock<double*> channelBufferDouble;\r
+ ScopedPointer<VST2BypassParameter> bypassParam;\r
\r
ScopedPointer<VSTXMLInfo> xmlInfo;\r
\r
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
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
\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
\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
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
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
}\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
}\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
}\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
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
\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
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
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
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
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
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
*/\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
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
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
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
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
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
\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
\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
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
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
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
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
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
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
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
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
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
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
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
{\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
&& 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
*/\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
\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
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
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
};\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
\r
void GenericAudioProcessorEditor::resized()\r
{\r
- view.setBounds (getLocalBounds());\r
+ pimpl->view.setBounds (getLocalBounds());\r
}\r
\r
} // namespace juce\r
\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
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
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
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
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
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
@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
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
\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
\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
\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
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
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
{\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
*/\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
/** 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
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
*/\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
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
/** 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
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
\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
\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
*/\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
\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
\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
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
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
*/\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
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
/** 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
#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
\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
//==============================================================================\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
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
}\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
#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
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
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
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
[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
{\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
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
\r
~ActiveProcess()\r
{\r
- if (readHandle != 0)\r
+ if (readHandle != nullptr)\r
fclose (readHandle);\r
\r
if (pipeHandle != 0)\r
\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
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
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
//==============================================================================\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
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
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
\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
\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
}\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
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
*/\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
{\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
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
*/\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
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
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
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
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
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
{\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
\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
\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
\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
\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
}\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
}\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
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
*/\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
*/\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
*/\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
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
}\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
{\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
if (isUsingDefault())\r
return defaultValue;\r
\r
+ if (delimiter.isNotEmpty())\r
+ return delimitedStringToVarArray (targetTree[targetProperty].toString());\r
+\r
return targetTree[targetProperty];\r
}\r
\r
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
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
/** 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
*/\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
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
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
{\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
{\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
\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
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
/** 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
\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
{\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
\r
size_t offsetMat = 0, offsetlhs = 0;\r
\r
- auto *dst = result.getRawDataPointer();\r
- auto *a = getRawDataPointer();\r
- auto *b = other.getRawDataPointer();\r
+ auto* dst = result.getRawDataPointer();\r
+ auto* a = getRawDataPointer();\r
+ auto* b = other.getRawDataPointer();\r
\r
for (size_t i = 0; i < n; ++i)\r
{\r
/** 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>::IIRPolyphaseAllpassStructure& structure) 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
+ auto* coeffs = structure.directPath.getReference (n).getRawCoefficients();\r
\r
if (structure.directPath[n].getFilterOrder() == 1)\r
{\r
\r
for (auto n = 0; n < structure.delayedPath.size(); n++)\r
{\r
- auto *coeffs = structure.delayedPath.getReference (n).getRawCoefficients();\r
+ auto* coeffs = structure.delayedPath.getReference (n).getRawCoefficients();\r
\r
if (structure.delayedPath[n].getFilterOrder() == 1)\r
{\r
\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
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
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
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
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
\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
*/\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
\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
/** 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
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
\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
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
\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
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
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
\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
//==============================================================================\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
\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
\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
\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
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
}\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
}\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
\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
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
}\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
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
\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
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
}\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
{\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
}\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
\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
\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
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
\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
\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
{\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
{\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
\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
\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
\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
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
\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
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
}\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
}\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
{\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
\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
\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
\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
\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
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
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
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
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
\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
\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
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
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
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
#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
\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
#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
+ 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
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
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
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
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
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
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
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
\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
{\r
int numClicks = 1;\r
\r
- if (! hasMouseMovedSignificantlySincePressed())\r
+ if (! isLongPressOrDrag())\r
{\r
for (int i = 1; i < numElementsInArray (mouseDowns); ++i)\r
{\r
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
\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
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
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
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
/** 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
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
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
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
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
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
+ auto* dragImage = [[NSWorkspace sharedWorkspace] iconForFile: nsFilename];\r
[dragItem setDraggingFrame: dragRect\r
contents: dragImage];\r
\r
startTimer (10);\r
}\r
\r
- JUCE_DECLARE_SINGLETON_SINGLETHREADED (OnScreenKeyboard, true)\r
+ JUCE_DECLARE_SINGLETON_SINGLETHREADED (OnScreenKeyboard, false)\r
\r
private:\r
OnScreenKeyboard()\r
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
}\r
\r
private:\r
- ValueWithDefault valueWithDefault;\r
+ ValueWithDefault& valueWithDefault;\r
Value sourceValue;\r
Array<var> mappings;\r
\r
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
\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
\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
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
\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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+\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
--- /dev/null
+/*\r
+ ==============================================================================\r
+\r
+ This file is part of the JUCE library.\r
+ Copyright (c) 2017 - ROLI Ltd.\r
+\r
+ JUCE is an open source library subject to commercial or open-source\r
+ licensing.\r
+\r
+ By using JUCE, you agree to the terms of both the JUCE 5 End-User License\r
+ Agreement and JUCE 5 Privacy Policy (both updated and effective as of the\r
+ 27th April 2017).\r
+\r
+ End User License Agreement: www.juce.com/juce-5-licence\r
+ Privacy Policy: www.juce.com/juce-5-privacy-policy\r
+\r
+ Or: You may also use this code under the terms of the GPL v3 (see\r
+ www.gnu.org/licenses).\r
+\r
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER\r
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE\r
+ DISCLAIMED.\r
+\r
+ ==============================================================================\r
+*/\r
+\r
+\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
//==============================================================================\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
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
{\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
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
\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
/** 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
virtual void textWasEdited();\r
\r
private:\r
+ bool isMultiLine;\r
+\r
class RemapperValueSourceWithDefault;\r
\r
class LabelComp;\r
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
\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
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
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
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
\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
\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
\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
\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
\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
\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